From 03c7b98b473f349dc53e9bcbf899790e18fb78f1 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 13 Jun 2024 03:02:33 +0400 Subject: [PATCH 001/220] fix: draft sr v2 voting script --- configs/config_holesky.py | 7 +- interfaces/v3/DepositSecurityModuleV3.json | 1 + scripts/scripts.code-workspace | 18 +++ scripts/staking_router_v2_holesky.py | 170 +++++++++++++++++++++ utils/config.py | 4 + 5 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 interfaces/v3/DepositSecurityModuleV3.json create mode 100644 scripts/scripts.code-workspace create mode 100644 scripts/staking_router_v2_holesky.py diff --git a/configs/config_holesky.py b/configs/config_holesky.py index e80a5038c..a16bc23af 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -23,6 +23,7 @@ LIDO = "0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034" LEGACY_ORACLE = "0x072f72BE3AcFE2c52715829F2CD9061A6C8fF019" NODE_OPERATORS_REGISTRY = "0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" +NOR_IMPL = "" # set address here after deploy # Aragon APM Repos VOTING_REPO = "0x2997EA0D07D79038D83Cb04b3BB9A2Bc512E3fDA" @@ -77,15 +78,19 @@ # LIDO_LOCATOR = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" +LIDO_LOCATOR_IMPL = "" # set address here after deploy WITHDRAWAL_QUEUE = "0xc7cc160b58F8Bb0baC94b80847E2CF2800565C50" ORACLE_DAEMON_CONFIG = "0xC01fC1F2787687Bc656EAc0356ba9Db6e6b7afb7" ORACLE_REPORT_SANITY_CHECKER = "0xF0d576c7d934bBeCc68FE15F1c5DAF98ea2B78bb" BURNER = "0x4E46BD7147ccf666E1d73A3A456fC7a68de82eCA" DEPOSIT_SECURITY_MODULE = "0x045dd46212A178428c088573A7d102B9d89a022A" +DEPOSIT_SECURITY_MODULE_V3 = "" # set address here after deploy ACCOUNTING_ORACLE = "0x4E97A3972ce8511D87F334dA17a2C332542a5246" +ACCOUNTING_ORACLE_IMPL = "" # set address here after deploy VALIDATORS_EXIT_BUS_ORACLE = "0xffDDF7025410412deaa05E3E1cE68FE53208afcb" EIP712_STETH = "0xE154732c5Eab277fd88a9fF6Bdff7805eD97BCB1" STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" +STAKING_ROUTER_IMPL = "" # set address herer after deploy WITHDRAWAL_VAULT_IMPL = "0xd517d9d04DA9B47dA23df91261bd3bF435BE964A" @@ -94,4 +99,4 @@ GATE_SEAL = "0x7f6FA688d4C12a2d51936680b241f3B0F0F9ca60" GATE_SEAL_PAUSE_DURATION = 518400 # 6 days GATE_SEAL_EXPIRY_TIMESTAMP = 1714521600 # 2024-05-01 00:00GMT -GATE_SEAL_COMMITTEE = "0x6165267E76D609465640bffc158aff7905D47B46" \ No newline at end of file +GATE_SEAL_COMMITTEE = "0x6165267E76D609465640bffc158aff7905D47B46" diff --git a/interfaces/v3/DepositSecurityModuleV3.json b/interfaces/v3/DepositSecurityModuleV3.json new file mode 100644 index 000000000..ed4961480 --- /dev/null +++ b/interfaces/v3/DepositSecurityModuleV3.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_lido","type":"address"},{"internalType":"address","name":"_depositContract","type":"address"},{"internalType":"address","name":"_stakingRouter","type":"address"},{"internalType":"uint256","name":"_maxDepositsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_minDepositBlockDistance","type":"uint256"},{"internalType":"uint256","name":"_pauseIntentValidityPeriodBlocks","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DepositInactiveModule","type":"error"},{"inputs":[],"name":"DepositNoQuorum","type":"error"},{"inputs":[],"name":"DepositNonceChanged","type":"error"},{"inputs":[],"name":"DepositRootChanged","type":"error"},{"inputs":[],"name":"DepositTooFrequent","type":"error"},{"inputs":[],"name":"DepositUnexpectedBlockHash","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"DuplicateAddress","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotAGuardian","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotAnOwner","type":"error"},{"inputs":[],"name":"PauseIntentExpired","type":"error"},{"inputs":[],"name":"SignaturesNotSorted","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"inputs":[{"internalType":"string","name":"parameter","type":"string"}],"name":"ZeroParameter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"GuardianQuorumChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MaxDepositsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinDepositBlockDistanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"PauseIntentValidityPeriodBlocksChanged","type":"event"},{"inputs":[],"name":"ATTEST_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"contract ILido","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_ROUTER","outputs":[{"internalType":"contract IStakingRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardians","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"canDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"depositCalldata","type":"bytes"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature[]","name":"sortedGuardianSignatures","type":"tuple[]"}],"name":"depositBufferedEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getGuardianIndex","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardianQuorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardians","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinDepositBlockDistance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseIntentValidityPeriodBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature","name":"sig","type":"tuple"}],"name":"pauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"removeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setGuardianQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMaxDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMinDepositBlockDistance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setPauseIntentValidityPeriodBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"unpauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"}]s \ No newline at end of file diff --git a/scripts/scripts.code-workspace b/scripts/scripts.code-workspace new file mode 100644 index 000000000..3f9c93ccd --- /dev/null +++ b/scripts/scripts.code-workspace @@ -0,0 +1,18 @@ +{ + "folders": [ + { + "path": ".." + }, + { + "path": "../../core" + }, + { + "path": "../../lido-cli" + } +], + "settings": { + "[json]": { + "editor.formatOnSave": false + } + } +} diff --git a/scripts/staking_router_v2_holesky.py b/scripts/staking_router_v2_holesky.py new file mode 100644 index 000000000..b91fd840a --- /dev/null +++ b/scripts/staking_router_v2_holesky.py @@ -0,0 +1,170 @@ +""" +SR V2 +1. Update locator implementation +2. Revoke pause role from old DSM +3. Revoke resume role from old DSM +4. Grant unvetting role to new DSM +5. Update SR implementation +6. Call finalize upgrade on SR +7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo +8. Update `NodeOperatorsRegistry` implementation +9. Finalize NOR upgrade +10. Update AO implementation to ${AO_IMPLEMENTATION}`, +11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +12. Grant manage consensus role to agent ${aragonAgentAddress}` +13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +""" + +import time + +from typing import Dict, Tuple, Optional +from utils.config import ( + get_deployer_account, + contracts, + LIDO_LOCATOR, + LIDO_LOCATOR_IMPL, + STAKING_ROUTER, + STAKING_ROUTER_IMPL, + NODE_OPERATORS_REGISTRY, + NOR_IMPL, + ACCOUNTING_ORACLE, + ACCOUNTING_ORACLE_IMPL, + VALIDATORS_EXIT_BUS_ORACLE, + AGENT, +) +from utils.permissions import encode_permission_revoke, encode_permission_grant + +from utils.repo import add_implementation_to_nor_app_repo + +from utils.kernel import update_app_implementation + +from utils.voting import bake_vote_items, confirm_vote_script, create_vote + +from brownie.network.transaction import TransactionReceipt + + +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000] +MAX_DEPOSITS_PER_BLOCK = [50] +MIN_DEPOSIT_BLOCK_DISTANCES = [25] +NOR_CONTENT_URI = "0x" + "00".repeat(51) # ? +NOR_VERSION = ["2", "0", "0"] +NOR_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 + + +def encode_locator_proxy_update(locator_proxy_address: str, implementation: str) -> Tuple[str, str]: + proxy = interface.LidoLocator(locator_proxy_address) + return proxy.address, proxy.proxy_upgradeTo.encode_input(implementation, b"") + + +def encode_staking_router_proxy_update(sr_proxy_address: str, implementation: str) -> Tuple[str, str]: + proxy = interface.StakingRouter(sr_proxy_address) + return proxy.address, proxy.proxy_upgradeTo.encode_input(implementation, b"") + + +def encode_staking_router_finalize(sr_proxy_address: str) -> Tuple[str, str]: + proxy = interface.StakingRouter(sr_proxy_address) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input( + PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES + ) + + +def encode_nor_finalize(nor_address: str) -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(nor_address) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_ao_proxy_update(ao_proxy: str, implementation: str) -> Tuple[str, str]: + proxy = interface.AccountingOracle(ao_proxy) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation, b"") + + +def encode_ao_finalize(ao: str) -> Tuple[str, str]: + proxy = interface.AccountingOracle(ao) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) + + +def encode_set_consensus_version(vebo: str) -> Tuple[str, str]: + proxy = interface.ValidatorExitBusOracle(vebo) + return proxy.address, proxy.setConsensusVersion(vebo) + + +def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: + """Prepare and run voting.""" + + call_script_items = [ + # 1) + encode_locator_proxy_update(LIDO_LOCATOR, LIDO_LOCATOR_IMPL), + # 2) + encode_permission_revoke( + contracts.staking_router, "STAKING_MODULE_PAUSE_ROLE", revoke_from=contracts.deposit_security_module + ), + # 3) + encode_permission_revoke( + contracts.staking_router, "STAKING_MODULE_RESUME_ROLE", revoke_from=contracts.deposit_security_module + ), + # 4) + encode_permission_grant( + grant_to=contracts.deposit_security_module_v3, + target_app=contracts.staking_router, + permission_name="STAKING_MODULE_UNVETTING_ROLE", + ), + # 5) + encode_staking_router_proxy_update(STAKING_ROUTER, STAKING_ROUTER_IMPL), + # 6) + encode_staking_router_finalize(STAKING_ROUTER), + # 7) + add_implementation_to_nor_app_repo(NOR_VERSION, NOR_IMPL, NOR_CONTENT_URI), + # 8) + update_app_implementation(NOR_APP_ID, NOR_IMPL), + # 9) + encode_nor_finalize(NODE_OPERATORS_REGISTRY), + # 10) + encode_ao_proxy_update(ACCOUNTING_ORACLE, ACCOUNTING_ORACLE_IMPL), + # 11) + encode_ao_finalize(ACCOUNTING_ORACLE), + # 12) + encode_permission_grant( + grant_to=VALIDATORS_EXIT_BUS_ORACLE, + target_app=AGENT, # ??? + permission_name="MANAGE_CONSENSUS_VERSION_ROLE", + ), + # 13) + encode_set_consensus_version(VALIDATORS_EXIT_BUS_ORACLE), + ] + + vote_desc_items = [ + "1. Update locator implementation", + "2. Revoke pause role from old DSM", + "3. Revoke resume role from old DSM", + "4. Grant unvetting role to new DSM", + "5. Update SR implementation", + "6. Call finalize upgrade on SR", + "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + "8. Update `NodeOperatorsRegistry` implementation", + "9. Finalize NOR upgrade", + "10. Update AO implementation to ${AO_IMPLEMENTATION}", + "11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + "12. Grant manage consensus role to agent ${aragonAgentAddress}", + "13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + ] + + vote_items = bake_vote_items(vote_desc_items, call_script_items) + + return confirm_vote_script(vote_items, silent) and list(create_vote(vote_items, tx_params)) + + +def main(): + tx_params = {"from": get_deployer_account()} + + # ???? + if get_is_live(): + tx_params["max_fee"] = "300 gwei" + tx_params["priority_fee"] = "2 gwei" + + vote_id, _ = start_vote(tx_params=tx_params, silent=False) + + vote_id >= 0 and print(f"Vote created: {vote_id}.") + + time.sleep(5) # hack for waiting thread #2. diff --git a/utils/config.py b/utils/config.py index 0cd0672d6..00dd17bb3 100644 --- a/utils/config.py +++ b/utils/config.py @@ -181,6 +181,10 @@ def legacy_oracle(self) -> interface.LegacyOracle: def deposit_security_module_v1(self) -> interface.DepositSecurityModule: return interface.DepositSecurityModuleV1(DEPOSIT_SECURITY_MODULE_V1) + @property + def deposit_security_module_v3(self) -> interface.DepositSecurityModule: + return interface.DepositSecurityModuleV3(DEPOSIT_SECURITY_MODULE_V3) + @property def deposit_security_module(self) -> interface.DepositSecurityModule: return interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE) From 4cc5886c33dbad454fe41349a98292626b2959d3 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 13 Jun 2024 21:27:01 +0400 Subject: [PATCH 002/220] fix: vote script --- configs/config_holesky.py | 11 +- interfaces/AccountingOracle.json | 1352 ++++++++++- interfaces/NodeOperatorsRegistry.json | 1635 ++++++++++++- interfaces/StakingRouter.json | 2507 +++++++++++++++++++- interfaces/v3/DepositSecurityModuleV3.json | 2 +- scripts/staking_router_v2_holesky.py | 54 +- 6 files changed, 5529 insertions(+), 32 deletions(-) diff --git a/configs/config_holesky.py b/configs/config_holesky.py index a16bc23af..934c8b730 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -23,7 +23,7 @@ LIDO = "0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034" LEGACY_ORACLE = "0x072f72BE3AcFE2c52715829F2CD9061A6C8fF019" NODE_OPERATORS_REGISTRY = "0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" -NOR_IMPL = "" # set address here after deploy +NOR_IMPL = "0x0c626FC4A447b01554518550e30600136864640B" # set address here after deploy # Aragon APM Repos VOTING_REPO = "0x2997EA0D07D79038D83Cb04b3BB9A2Bc512E3fDA" @@ -78,19 +78,20 @@ # LIDO_LOCATOR = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -LIDO_LOCATOR_IMPL = "" # set address here after deploy +LIDO_LOCATOR_IMPL = "0x2F54D1563963fC04770E85AF819c89Dc807f6a06" # set address here after deploy WITHDRAWAL_QUEUE = "0xc7cc160b58F8Bb0baC94b80847E2CF2800565C50" ORACLE_DAEMON_CONFIG = "0xC01fC1F2787687Bc656EAc0356ba9Db6e6b7afb7" ORACLE_REPORT_SANITY_CHECKER = "0xF0d576c7d934bBeCc68FE15F1c5DAF98ea2B78bb" +ORACLE_REPORT_SANITY_CHECKER_V2 = "0x158d291D8b47F056751cfF47d1eEcd19FDF9B6f8" # should be changed for new BURNER = "0x4E46BD7147ccf666E1d73A3A456fC7a68de82eCA" DEPOSIT_SECURITY_MODULE = "0x045dd46212A178428c088573A7d102B9d89a022A" -DEPOSIT_SECURITY_MODULE_V3 = "" # set address here after deploy +DEPOSIT_SECURITY_MODULE_V3 = "0xA21DDc1f17dF41589BC6A5209292AED2dF61Cc94" # set address here after deploy ACCOUNTING_ORACLE = "0x4E97A3972ce8511D87F334dA17a2C332542a5246" -ACCOUNTING_ORACLE_IMPL = "" # set address here after deploy +ACCOUNTING_ORACLE_IMPL = "0x2A590C461Db46bca129E8dBe5C3998A8fF402e76" # set address here after deploy VALIDATORS_EXIT_BUS_ORACLE = "0xffDDF7025410412deaa05E3E1cE68FE53208afcb" EIP712_STETH = "0xE154732c5Eab277fd88a9fF6Bdff7805eD97BCB1" STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" -STAKING_ROUTER_IMPL = "" # set address herer after deploy +STAKING_ROUTER_IMPL = "0x33E45b187da34826aBCEDA1039231Be46f1b05Af" # set address here after deploy WITHDRAWAL_VAULT_IMPL = "0xd517d9d04DA9B47dA23df91261bd3bF435BE964A" diff --git a/interfaces/AccountingOracle.json b/interfaces/AccountingOracle.json index 0e92040e5..f422cbaa0 100644 --- a/interfaces/AccountingOracle.json +++ b/interfaces/AccountingOracle.json @@ -1 +1,1351 @@ -[{"inputs":[{"internalType":"address","name":"lidoLocator","type":"address"},{"internalType":"address","name":"lido","type":"address"},{"internalType":"address","name":"legacyOracle","type":"address"},{"internalType":"uint256","name":"secondsPerSlot","type":"uint256"},{"internalType":"uint256","name":"genesisTime","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressCannotBeSame","type":"error"},{"inputs":[],"name":"AddressCannotBeZero","type":"error"},{"inputs":[],"name":"AdminCannotBeZero","type":"error"},{"inputs":[],"name":"CannotSubmitExtraDataBeforeMainData","type":"error"},{"inputs":[],"name":"ExtraDataAlreadyProcessed","type":"error"},{"inputs":[],"name":"ExtraDataHashCannotBeZeroForNonEmptyData","type":"error"},{"inputs":[],"name":"ExtraDataItemsCountCannotBeZeroForNonEmptyData","type":"error"},{"inputs":[],"name":"ExtraDataListOnlySupportsSingleTx","type":"error"},{"inputs":[],"name":"HashCannotBeZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"}],"name":"IncorrectOracleMigration","type":"error"},{"inputs":[{"internalType":"uint256","name":"initialRefSlot","type":"uint256"},{"internalType":"uint256","name":"processingRefSlot","type":"uint256"}],"name":"InitialRefSlotCannotBeLessThanProcessingOne","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[],"name":"InvalidExitedValidatorsData","type":"error"},{"inputs":[{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"name":"InvalidExtraDataItem","type":"error"},{"inputs":[{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"name":"InvalidExtraDataSortOrder","type":"error"},{"inputs":[],"name":"LegacyOracleCannotBeZero","type":"error"},{"inputs":[],"name":"LidoCannotBeZero","type":"error"},{"inputs":[],"name":"LidoLocatorCannotBeZero","type":"error"},{"inputs":[],"name":"NoConsensusReportToProcess","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ProcessingDeadlineMissed","type":"error"},{"inputs":[],"name":"RefSlotAlreadyProcessing","type":"error"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"prevRefSlot","type":"uint256"}],"name":"RefSlotCannotDecrease","type":"error"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"processingRefSlot","type":"uint256"}],"name":"RefSlotMustBeGreaterThanProcessingOne","type":"error"},{"inputs":[],"name":"SecondsPerSlotCannotBeZero","type":"error"},{"inputs":[],"name":"SenderIsNotTheConsensusContract","type":"error"},{"inputs":[],"name":"SenderNotAllowed","type":"error"},{"inputs":[],"name":"UnexpectedChainConfig","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedVersion","type":"uint256"},{"internalType":"uint256","name":"receivedVersion","type":"uint256"}],"name":"UnexpectedConsensusVersion","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[{"internalType":"bytes32","name":"consensusHash","type":"bytes32"},{"internalType":"bytes32","name":"receivedHash","type":"bytes32"}],"name":"UnexpectedDataHash","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedFormat","type":"uint256"},{"internalType":"uint256","name":"receivedFormat","type":"uint256"}],"name":"UnexpectedExtraDataFormat","type":"error"},{"inputs":[{"internalType":"bytes32","name":"consensusHash","type":"bytes32"},{"internalType":"bytes32","name":"receivedHash","type":"bytes32"}],"name":"UnexpectedExtraDataHash","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedIndex","type":"uint256"},{"internalType":"uint256","name":"receivedIndex","type":"uint256"}],"name":"UnexpectedExtraDataIndex","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedCount","type":"uint256"},{"internalType":"uint256","name":"receivedCount","type":"uint256"}],"name":"UnexpectedExtraDataItemsCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"consensusRefSlot","type":"uint256"},{"internalType":"uint256","name":"dataRefSlot","type":"uint256"}],"name":"UnexpectedRefSlot","type":"error"},{"inputs":[{"internalType":"uint256","name":"format","type":"uint256"}],"name":"UnsupportedExtraDataFormat","type":"error"},{"inputs":[{"internalType":"uint256","name":"itemIndex","type":"uint256"},{"internalType":"uint256","name":"dataType","type":"uint256"}],"name":"UnsupportedExtraDataType","type":"error"},{"inputs":[],"name":"VersionCannotBeSame","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"prevAddr","type":"address"}],"name":"ConsensusHashContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"version","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"prevVersion","type":"uint256"}],"name":"ConsensusVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemsProcessed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemsCount","type":"uint256"}],"name":"ExtraDataSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"ProcessingStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"ReportDiscarded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"}],"name":"ReportSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"processedItemsCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemsCount","type":"uint256"}],"name":"WarnExtraDataIncompleteProcessing","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"}],"name":"WarnProcessingMissed","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_DATA_FORMAT_EMPTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_DATA_FORMAT_LIST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_DATA_TYPE_EXITED_VALIDATORS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_DATA_TYPE_STUCK_VALIDATORS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GENESIS_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LEGACY_ORACLE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LOCATOR","outputs":[{"internalType":"contract ILidoLocator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_CONSENSUS_CONTRACT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_CONSENSUS_VERSION_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_PER_SLOT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUBMIT_DATA_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"}],"name":"discardConsensusReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getConsensusContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusReport","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"},{"internalType":"bool","name":"processingStarted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessingRefSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProcessingState","outputs":[{"components":[{"internalType":"uint256","name":"currentFrameRefSlot","type":"uint256"},{"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"},{"internalType":"bytes32","name":"mainDataHash","type":"bytes32"},{"internalType":"bool","name":"mainDataSubmitted","type":"bool"},{"internalType":"bytes32","name":"extraDataHash","type":"bytes32"},{"internalType":"uint256","name":"extraDataFormat","type":"uint256"},{"internalType":"bool","name":"extraDataSubmitted","type":"bool"},{"internalType":"uint256","name":"extraDataItemsCount","type":"uint256"},{"internalType":"uint256","name":"extraDataItemsSubmitted","type":"uint256"}],"internalType":"struct AccountingOracle.ProcessingState","name":"result","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"consensusContract","type":"address"},{"internalType":"uint256","name":"consensusVersion","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"consensusContract","type":"address"},{"internalType":"uint256","name":"consensusVersion","type":"uint256"},{"internalType":"uint256","name":"lastProcessingRefSlot","type":"uint256"}],"name":"initializeWithoutMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setConsensusContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"}],"name":"setConsensusVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"reportHash","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"submitConsensusReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"consensusVersion","type":"uint256"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"numValidators","type":"uint256"},{"internalType":"uint256","name":"clBalanceGwei","type":"uint256"},{"internalType":"uint256[]","name":"stakingModuleIdsWithNewlyExitedValidators","type":"uint256[]"},{"internalType":"uint256[]","name":"numExitedValidatorsByStakingModule","type":"uint256[]"},{"internalType":"uint256","name":"withdrawalVaultBalance","type":"uint256"},{"internalType":"uint256","name":"elRewardsVaultBalance","type":"uint256"},{"internalType":"uint256","name":"sharesRequestedToBurn","type":"uint256"},{"internalType":"uint256[]","name":"withdrawalFinalizationBatches","type":"uint256[]"},{"internalType":"uint256","name":"simulatedShareRate","type":"uint256"},{"internalType":"bool","name":"isBunkerMode","type":"bool"},{"internalType":"uint256","name":"extraDataFormat","type":"uint256"},{"internalType":"bytes32","name":"extraDataHash","type":"bytes32"},{"internalType":"uint256","name":"extraDataItemsCount","type":"uint256"}],"internalType":"struct AccountingOracle.ReportData","name":"data","type":"tuple"},{"internalType":"uint256","name":"contractVersion","type":"uint256"}],"name":"submitReportData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"submitReportExtraDataEmpty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"items","type":"bytes"}],"name":"submitReportExtraDataList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file +[ + { + "inputs": [ + { + "internalType": "address", + "name": "lidoLocator", + "type": "address" + }, + { + "internalType": "address", + "name": "lido", + "type": "address" + }, + { + "internalType": "address", + "name": "legacyOracle", + "type": "address" + }, + { + "internalType": "uint256", + "name": "secondsPerSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "genesisTime", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AddressCannotBeSame", + "type": "error" + }, + { + "inputs": [], + "name": "AddressCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "AdminCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "CannotSubmitExtraDataBeforeMainData", + "type": "error" + }, + { + "inputs": [], + "name": "ExtraDataAlreadyProcessed", + "type": "error" + }, + { + "inputs": [], + "name": "ExtraDataHashCannotBeZeroForNonEmptyData", + "type": "error" + }, + { + "inputs": [], + "name": "ExtraDataItemsCountCannotBeZeroForNonEmptyData", + "type": "error" + }, + { + "inputs": [], + "name": "HashCannotBeZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "code", + "type": "uint256" + } + ], + "name": "IncorrectOracleMigration", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "initialRefSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingRefSlot", + "type": "uint256" + } + ], + "name": "InitialRefSlotCannotBeLessThanProcessingOne", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidContractVersionIncrement", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidExitedValidatorsData", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "itemIndex", + "type": "uint256" + } + ], + "name": "InvalidExtraDataItem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "itemIndex", + "type": "uint256" + } + ], + "name": "InvalidExtraDataSortOrder", + "type": "error" + }, + { + "inputs": [], + "name": "LegacyOracleCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "LidoCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "LidoLocatorCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "NoConsensusReportToProcess", + "type": "error" + }, + { + "inputs": [], + "name": "NonZeroContractVersionOnInit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "ProcessingDeadlineMissed", + "type": "error" + }, + { + "inputs": [], + "name": "RefSlotAlreadyProcessing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "prevRefSlot", + "type": "uint256" + } + ], + "name": "RefSlotCannotDecrease", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingRefSlot", + "type": "uint256" + } + ], + "name": "RefSlotMustBeGreaterThanProcessingOne", + "type": "error" + }, + { + "inputs": [], + "name": "SecondsPerSlotCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "SenderIsNotTheConsensusContract", + "type": "error" + }, + { + "inputs": [], + "name": "SenderNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "UnexpectedChainConfig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedVersion", + "type": "uint256" + } + ], + "name": "UnexpectedConsensusVersion", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "UnexpectedContractVersion", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "consensusHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "receivedHash", + "type": "bytes32" + } + ], + "name": "UnexpectedDataHash", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedFormat", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedFormat", + "type": "uint256" + } + ], + "name": "UnexpectedExtraDataFormat", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "consensusHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "receivedHash", + "type": "bytes32" + } + ], + "name": "UnexpectedExtraDataHash", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedIndex", + "type": "uint256" + } + ], + "name": "UnexpectedExtraDataIndex", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedCount", + "type": "uint256" + } + ], + "name": "UnexpectedExtraDataItemsCount", + "type": "error" + }, + { + "inputs": [], + "name": "UnexpectedExtraDataLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "consensusRefSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dataRefSlot", + "type": "uint256" + } + ], + "name": "UnexpectedRefSlot", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "format", + "type": "uint256" + } + ], + "name": "UnsupportedExtraDataFormat", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "itemIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dataType", + "type": "uint256" + } + ], + "name": "UnsupportedExtraDataType", + "type": "error" + }, + { + "inputs": [], + "name": "VersionCannotBeSame", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "prevAddr", + "type": "address" + } + ], + "name": "ConsensusHashContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "prevVersion", + "type": "uint256" + } + ], + "name": "ConsensusVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + } + ], + "name": "ContractVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "itemsProcessed", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "itemsCount", + "type": "uint256" + } + ], + "name": "ExtraDataSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "ProcessingStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "ReportDiscarded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "processingDeadlineTime", + "type": "uint256" + } + ], + "name": "ReportSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "processedItemsCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "itemsCount", + "type": "uint256" + } + ], + "name": "WarnExtraDataIncompleteProcessing", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + } + ], + "name": "WarnProcessingMissed", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_DATA_FORMAT_EMPTY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_DATA_FORMAT_LIST", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_DATA_TYPE_EXITED_VALIDATORS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_DATA_TYPE_STUCK_VALIDATORS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GENESIS_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LEGACY_ORACLE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LIDO", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOCATOR", + "outputs": [ + { + "internalType": "contract ILidoLocator", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_CONSENSUS_CONTRACT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_CONSENSUS_VERSION_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SECONDS_PER_SLOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUBMIT_DATA_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + } + ], + "name": "discardConsensusReport", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + } + ], + "name": "finalizeUpgrade_v2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusReport", + "outputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingDeadlineTime", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "processingStarted", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastProcessingRefSlot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProcessingState", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "currentFrameRefSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingDeadlineTime", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "mainDataHash", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "mainDataSubmitted", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "extraDataHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "extraDataFormat", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "extraDataSubmitted", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "extraDataItemsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "extraDataItemsSubmitted", + "type": "uint256" + } + ], + "internalType": "struct AccountingOracle.ProcessingState", + "name": "result", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "consensusContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "consensusContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastProcessingRefSlot", + "type": "uint256" + } + ], + "name": "initializeWithoutMigration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "setConsensusContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "version", + "type": "uint256" + } + ], + "name": "setConsensusVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "reportHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "submitConsensusReport", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "clBalanceGwei", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "stakingModuleIdsWithNewlyExitedValidators", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "numExitedValidatorsByStakingModule", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "withdrawalVaultBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "elRewardsVaultBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sharesRequestedToBurn", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "withdrawalFinalizationBatches", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "simulatedShareRate", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isBunkerMode", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "extraDataFormat", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "extraDataHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "extraDataItemsCount", + "type": "uint256" + } + ], + "internalType": "struct AccountingOracle.ReportData", + "name": "data", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "contractVersion", + "type": "uint256" + } + ], + "name": "submitReportData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "submitReportExtraDataEmpty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "submitReportExtraDataList", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] \ No newline at end of file diff --git a/interfaces/NodeOperatorsRegistry.json b/interfaces/NodeOperatorsRegistry.json index 632231338..2e8914d97 100644 --- a/interfaces/NodeOperatorsRegistry.json +++ b/interfaces/NodeOperatorsRegistry.json @@ -1 +1,1634 @@ -[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_keysCount","type":"uint256"},{"name":"_publicKeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getType","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"clearNodeOperatorPenalty","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_offset","type":"uint256"},{"name":"_limit","type":"uint256"}],"name":"getNodeOperatorIds","outputs":[{"name":"nodeOperatorIds","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_offset","type":"uint256"},{"name":"_limit","type":"uint256"}],"name":"getSigningKeys","outputs":[{"name":"pubkeys","type":"bytes"},{"name":"signatures","type":"bytes"},{"name":"used","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fromIndex","type":"uint256"},{"name":"_keysCount","type":"uint256"}],"name":"removeSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorIsActive","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_name","type":"string"}],"name":"setNodeOperatorName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_totalRewardShares","type":"uint256"}],"name":"getRewardsDistribution","outputs":[{"name":"recipients","type":"address[]"},{"name":"shares","type":"uint256[]"},{"name":"penalized","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_indexFrom","type":"uint256"},{"name":"_indexTo","type":"uint256"}],"name":"invalidateReadyToDepositKeysRange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_locator","type":"address"},{"name":"_type","type":"bytes32"},{"name":"_stuckPenaltyDelay","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_delay","type":"uint256"}],"name":"setStuckPenaltyDelay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStuckPenaltyDelay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fromIndex","type":"uint256"},{"name":"_keysCount","type":"uint256"}],"name":"removeSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"isOperatorPenalized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"deactivateNodeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"STAKING_ROUTER_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_keysCount","type":"uint256"},{"name":"_publicKeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getActiveNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_rewardAddress","type":"address"}],"name":"addNodeOperator","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getContractVersion","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getUnusedSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"onRewardsMinted","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_NODE_OPERATOR_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"onWithdrawalCredentialsChanged","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"activateNodeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_rewardAddress","type":"address"}],"name":"setNodeOperatorRewardAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fullInfo","type":"bool"}],"name":"getNodeOperator","outputs":[{"name":"active","type":"bool"},{"name":"name","type":"string"},{"name":"rewardAddress","type":"address"},{"name":"totalVettedValidators","type":"uint64"},{"name":"totalExitedValidators","type":"uint64"},{"name":"totalAddedValidators","type":"uint64"},{"name":"totalDepositedValidators","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_locator","type":"address"},{"name":"_type","type":"bytes32"},{"name":"_stuckPenaltyDelay","type":"uint256"}],"name":"finalizeUpgrade_v2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStakingModuleSummary","outputs":[{"name":"totalExitedValidators","type":"uint256"},{"name":"totalDepositedValidators","type":"uint256"},{"name":"depositableValidatorsCount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorIds","type":"bytes"},{"name":"_exitedValidatorsCounts","type":"bytes"}],"name":"updateExitedValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorIds","type":"bytes"},{"name":"_stuckValidatorsCounts","type":"bytes"}],"name":"updateStuckValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_refundedValidatorsCount","type":"uint256"}],"name":"updateRefundedValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_isTargetLimitActive","type":"bool"},{"name":"_targetLimit","type":"uint256"}],"name":"updateTargetValidatorsLimits","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_vettedSigningKeysCount","type":"uint64"}],"name":"setNodeOperatorStakingLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorSummary","outputs":[{"name":"isTargetLimitActive","type":"bool"},{"name":"targetValidatorsCount","type":"uint256"},{"name":"stuckValidatorsCount","type":"uint256"},{"name":"refundedValidatorsCount","type":"uint256"},{"name":"stuckPenaltyEndTimestamp","type":"uint256"},{"name":"totalExitedValidators","type":"uint256"},{"name":"totalDepositedValidators","type":"uint256"},{"name":"depositableValidatorsCount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"getSigningKey","outputs":[{"name":"key","type":"bytes"},{"name":"depositSignature","type":"bytes"},{"name":"used","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NODE_OPERATOR_NAME_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_depositsCount","type":"uint256"},{"name":"","type":"bytes"}],"name":"obtainDepositData","outputs":[{"name":"publicKeys","type":"bytes"},{"name":"signatures","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getKeysOpIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNonce","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLocator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SET_NODE_OPERATOR_LIMIT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getTotalSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_STUCK_PENALTY_DELAY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"onExitedAndStuckValidatorsCountsUpdated","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NODE_OPERATORS_COUNT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKeyOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_exitedValidatorsCount","type":"uint256"},{"name":"_stuckValidatorsCount","type":"uint256"}],"name":"unsafeUpdateValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_SIGNING_KEYS","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"isOperatorPenaltyCleared","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"stakingLimit","type":"uint64"}],"name":"NodeOperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"NodeOperatorActiveSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"name","type":"string"}],"name":"NodeOperatorNameSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"rewardAddress","type":"address"}],"name":"NodeOperatorRewardAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"totalKeysTrimmed","type":"uint64"}],"name":"NodeOperatorTotalKeysTrimmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"keysOpIndex","type":"uint256"}],"name":"KeysOpIndexSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"moduleType","type":"bytes32"}],"name":"StakingModuleTypeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"sharesAmount","type":"uint256"}],"name":"RewardsDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"locatorAddress","type":"address"}],"name":"LocatorContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"approvedValidatorsCount","type":"uint256"}],"name":"VettedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"depositedValidatorsCount","type":"uint256"}],"name":"DepositedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"exitedValidatorsCount","type":"uint256"}],"name":"ExitedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"totalValidatorsCount","type":"uint256"}],"name":"TotalSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nonce","type":"uint256"}],"name":"NonceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"stuckPenaltyDelay","type":"uint256"}],"name":"StuckPenaltyDelayChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"stuckValidatorsCount","type":"uint256"},{"indexed":false,"name":"refundedValidatorsCount","type":"uint256"},{"indexed":false,"name":"stuckPenaltyEndTimestamp","type":"uint256"}],"name":"StuckPenaltyStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"targetValidatorsCount","type":"uint256"}],"name":"TargetValidatorsCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipientAddress","type":"address"},{"indexed":false,"name":"sharesPenalizedAmount","type":"uint256"}],"name":"NodeOperatorPenalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}] \ No newline at end of file +[ + { + "constant": true, + "inputs": [], + "name": "hasInitialized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_targetLimitMode", + "type": "uint256" + }, + { + "name": "_targetLimit", + "type": "uint256" + } + ], + "name": "updateTargetValidatorsLimits", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + }, + { + "name": "_publicKeys", + "type": "bytes" + }, + { + "name": "_signatures", + "type": "bytes" + } + ], + "name": "addSigningKeys", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getType", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_script", + "type": "bytes" + } + ], + "name": "getEVMScriptExecutor", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "clearNodeOperatorPenalty", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getRecoveryVault", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_limit", + "type": "uint256" + } + ], + "name": "getNodeOperatorIds", + "outputs": [ + { + "name": "nodeOperatorIds", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_limit", + "type": "uint256" + } + ], + "name": "getSigningKeys", + "outputs": [ + { + "name": "pubkeys", + "type": "bytes" + }, + { + "name": "signatures", + "type": "bytes" + }, + { + "name": "used", + "type": "bool[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fromIndex", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + } + ], + "name": "removeSigningKeysOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getNodeOperatorIsActive", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_name", + "type": "string" + } + ], + "name": "setNodeOperatorName", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_totalRewardShares", + "type": "uint256" + } + ], + "name": "getRewardsDistribution", + "outputs": [ + { + "name": "recipients", + "type": "address[]" + }, + { + "name": "shares", + "type": "uint256[]" + }, + { + "name": "penalized", + "type": "bool[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_indexFrom", + "type": "uint256" + }, + { + "name": "_indexTo", + "type": "uint256" + } + ], + "name": "invalidateReadyToDepositKeysRange", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_locator", + "type": "address" + }, + { + "name": "_type", + "type": "bytes32" + }, + { + "name": "_stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_delay", + "type": "uint256" + } + ], + "name": "setStuckPenaltyDelay", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "finalizeUpgrade_v3", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getStuckPenaltyDelay", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "removeSigningKey", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getRewardDistributionState", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fromIndex", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + } + ], + "name": "removeSigningKeys", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "isOperatorPenalized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "deactivateNodeOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "token", + "type": "address" + } + ], + "name": "allowRecoverability", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "STAKING_ROUTER_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + }, + { + "name": "_publicKeys", + "type": "bytes" + }, + { + "name": "_signatures", + "type": "bytes" + } + ], + "name": "addSigningKeysOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "appId", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getActiveNodeOperatorsCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "_rewardAddress", + "type": "address" + } + ], + "name": "addNodeOperator", + "outputs": [ + { + "name": "id", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getInitializationBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getUnusedSigningKeyCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "onRewardsMinted", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MANAGE_NODE_OPERATOR_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "distributeReward", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "onWithdrawalCredentialsChanged", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "activateNodeOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_rewardAddress", + "type": "address" + } + ], + "name": "setNodeOperatorRewardAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fullInfo", + "type": "bool" + } + ], + "name": "getNodeOperator", + "outputs": [ + { + "name": "active", + "type": "bool" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "rewardAddress", + "type": "address" + }, + { + "name": "totalVettedValidators", + "type": "uint64" + }, + { + "name": "totalExitedValidators", + "type": "uint64" + }, + { + "name": "totalAddedValidators", + "type": "uint64" + }, + { + "name": "totalDepositedValidators", + "type": "uint64" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_locator", + "type": "address" + }, + { + "name": "_type", + "type": "bytes32" + }, + { + "name": "_stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "finalizeUpgrade_v2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getStakingModuleSummary", + "outputs": [ + { + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_exitedValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateExitedValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_stuckValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateStuckValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + } + ], + "name": "transferToVault", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_sender", + "type": "address" + }, + { + "name": "_role", + "type": "bytes32" + }, + { + "name": "_params", + "type": "uint256[]" + } + ], + "name": "canPerform", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_refundedValidatorsCount", + "type": "uint256" + } + ], + "name": "updateRefundedValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getEVMScriptRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getNodeOperatorsCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_vettedSigningKeysCount", + "type": "uint64" + } + ], + "name": "setNodeOperatorStakingLimit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getNodeOperatorSummary", + "outputs": [ + { + "name": "targetLimitMode", + "type": "uint256" + }, + { + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "getSigningKey", + "outputs": [ + { + "name": "key", + "type": "bytes" + }, + { + "name": "depositSignature", + "type": "bytes" + }, + { + "name": "used", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_NODE_OPERATOR_NAME_LENGTH", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_vettedSigningKeysCounts", + "type": "bytes" + } + ], + "name": "decreaseVettedSigningKeysCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_depositsCount", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "obtainDepositData", + "outputs": [ + { + "name": "publicKeys", + "type": "bytes" + }, + { + "name": "signatures", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getKeysOpIndex", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kernel", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getLocator", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "SET_NODE_OPERATOR_LIMIT_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getTotalSigningKeyCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isPetrified", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_STUCK_PENALTY_DELAY", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "onExitedAndStuckValidatorsCountsUpdated", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_NODE_OPERATORS_COUNT", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "removeSigningKeyOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_exitedValidatorsCount", + "type": "uint256" + }, + { + "name": "_stuckValidatorsCount", + "type": "uint256" + } + ], + "name": "unsafeUpdateValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MANAGE_SIGNING_KEYS", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "isOperatorPenaltyCleared", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "name", + "type": "string" + }, + { + "indexed": false, + "name": "rewardAddress", + "type": "address" + }, + { + "indexed": false, + "name": "stakingLimit", + "type": "uint64" + } + ], + "name": "NodeOperatorAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "active", + "type": "bool" + } + ], + "name": "NodeOperatorActiveSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "name", + "type": "string" + } + ], + "name": "NodeOperatorNameSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "rewardAddress", + "type": "address" + } + ], + "name": "NodeOperatorRewardAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalKeysTrimmed", + "type": "uint64" + } + ], + "name": "NodeOperatorTotalKeysTrimmed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "keysOpIndex", + "type": "uint256" + } + ], + "name": "KeysOpIndexSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "moduleType", + "type": "bytes32" + } + ], + "name": "StakingModuleTypeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "rewardAddress", + "type": "address" + }, + { + "indexed": false, + "name": "sharesAmount", + "type": "uint256" + } + ], + "name": "RewardsDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "state", + "type": "uint8" + } + ], + "name": "RewardDistributionStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "locatorAddress", + "type": "address" + } + ], + "name": "LocatorContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "approvedValidatorsCount", + "type": "uint256" + } + ], + "name": "VettedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "depositedValidatorsCount", + "type": "uint256" + } + ], + "name": "DepositedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "exitedValidatorsCount", + "type": "uint256" + } + ], + "name": "ExitedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalValidatorsCount", + "type": "uint256" + } + ], + "name": "TotalSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "nonce", + "type": "uint256" + } + ], + "name": "NonceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "StuckPenaltyDelayChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + } + ], + "name": "StuckPenaltyStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "targetLimitMode", + "type": "uint256" + } + ], + "name": "TargetValidatorsCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "recipientAddress", + "type": "address" + }, + { + "indexed": false, + "name": "sharesPenalizedAmount", + "type": "uint256" + } + ], + "name": "NodeOperatorPenalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "version", + "type": "uint256" + } + ], + "name": "ContractVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "executor", + "type": "address" + }, + { + "indexed": false, + "name": "script", + "type": "bytes" + }, + { + "indexed": false, + "name": "input", + "type": "bytes" + }, + { + "indexed": false, + "name": "returnData", + "type": "bytes" + } + ], + "name": "ScriptResult", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "vault", + "type": "address" + }, + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "RecoverToVault", + "type": "event" + } + ] \ No newline at end of file diff --git a/interfaces/StakingRouter.json b/interfaces/StakingRouter.json index c72053cdf..dfd058948 100644 --- a/interfaces/StakingRouter.json +++ b/interfaces/StakingRouter.json @@ -1 +1,2506 @@ -[{"inputs":[{"internalType":"address","name":"_depositContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AppAuthLidoFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"firstArrayLength","type":"uint256"},{"internalType":"uint256","name":"secondArrayLength","type":"uint256"}],"name":"ArraysLengthMismatch","type":"error"},{"inputs":[],"name":"DepositContractZeroAddress","type":"error"},{"inputs":[],"name":"DirectETHTransfer","type":"error"},{"inputs":[],"name":"EmptyWithdrawalsCredentials","type":"error"},{"inputs":[],"name":"ExitedValidatorsCountCannotDecrease","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[{"internalType":"uint256","name":"etherValue","type":"uint256"},{"internalType":"uint256","name":"depositsCount","type":"uint256"}],"name":"InvalidDepositsValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidPublicKeysBatchLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"}],"name":"InvalidReportData","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidSignaturesBatchLength","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"reportedExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"depositedValidatorsCount","type":"uint256"}],"name":"ReportedExitedValidatorsExceedDeposited","type":"error"},{"inputs":[],"name":"StakingModuleAddressExists","type":"error"},{"inputs":[],"name":"StakingModuleNotActive","type":"error"},{"inputs":[],"name":"StakingModuleNotPaused","type":"error"},{"inputs":[],"name":"StakingModuleStatusTheSame","type":"error"},{"inputs":[],"name":"StakingModuleUnregistered","type":"error"},{"inputs":[],"name":"StakingModuleWrongName","type":"error"},{"inputs":[],"name":"StakingModulesLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOpExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOpStuckValidatorsCount","type":"uint256"}],"name":"UnexpectedCurrentValidatorsCount","type":"error"},{"inputs":[],"name":"UnrecoverableModuleError","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ValueOver100Percent","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"ExitedAndStuckValidatorsCountsUpdateFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"RewardsMintedReportFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"address","name":"stakingModule","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"createdBy","type":"address"}],"name":"StakingModuleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unreportedExitedValidatorsCount","type":"uint256"}],"name":"StakingModuleExitedValidatorsIncompleteReporting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakingModuleFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"treasuryFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleFeesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"enum StakingRouter.StakingModuleStatus","name":"status","type":"uint8"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleStatusSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"targetShare","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleTargetShareSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakingRouterETHDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"WithdrawalCredentialsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"WithdrawalsCredentialsChangeFailed","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_PRECISION_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_WITHDRAWAL_CREDENTIALS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STAKING_MODULES_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STAKING_MODULE_NAME_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REPORT_EXITED_VALIDATORS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REPORT_REWARDS_MINTED_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_MANAGE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_PAUSE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_RESUME_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNSAFE_SET_EXITED_VALIDATORS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_stakingModuleAddress","type":"address"},{"internalType":"uint256","name":"_targetShare","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"addStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositsCount","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_depositCalldata","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getAllNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllStakingModuleDigests","outputs":[{"components":[{"internalType":"uint256","name":"nodeOperatorsCount","type":"uint256"},{"internalType":"uint256","name":"activeNodeOperatorsCount","type":"uint256"},{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.StakingModuleDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositsCount","type":"uint256"}],"name":"getDepositsAllocation","outputs":[{"internalType":"uint256","name":"allocated","type":"uint256"},{"internalType":"uint256[]","name":"allocations","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLido","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256[]","name":"_nodeOperatorIds","type":"uint256[]"}],"name":"getNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"digests","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorSummary","outputs":[{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingFeeAggregateDistribution","outputs":[{"internalType":"uint96","name":"modulesFee","type":"uint96"},{"internalType":"uint96","name":"treasuryFee","type":"uint96"},{"internalType":"uint256","name":"basePrecision","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingFeeAggregateDistributionE4Precision","outputs":[{"internalType":"uint16","name":"modulesFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModule","outputs":[{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleActiveValidatorsCount","outputs":[{"internalType":"uint256","name":"activeValidatorsCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"}],"name":"getStakingModuleDigests","outputs":[{"components":[{"internalType":"uint256","name":"nodeOperatorsCount","type":"uint256"},{"internalType":"uint256","name":"activeNodeOperatorsCount","type":"uint256"},{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.StakingModuleDigest[]","name":"digests","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModuleIds","outputs":[{"internalType":"uint256[]","name":"stakingModuleIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsDepositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsStopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleLastDepositBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_maxDepositsValue","type":"uint256"}],"name":"getStakingModuleMaxDepositsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleStatus","outputs":[{"internalType":"enum StakingRouter.StakingModuleStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleSummary","outputs":[{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModules","outputs":[{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule[]","name":"res","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModulesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingRewardsDistribution","outputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"stakingModuleIds","type":"uint256[]"},{"internalType":"uint96[]","name":"stakingModuleFees","type":"uint96[]"},{"internalType":"uint96","name":"totalFee","type":"uint96"},{"internalType":"uint256","name":"precisionPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalFeeE4Precision","outputs":[{"internalType":"uint16","name":"totalFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"hasStakingModule","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_lido","type":"address"},{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"onValidatorsCountsByNodeOperatorReportingFinished","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"pauseStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_totalShares","type":"uint256[]"}],"name":"reportRewardsMinted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_exitedValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleExitedValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_stuckValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleStuckValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"resumeStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"enum StakingRouter.StakingModuleStatus","name":"_status","type":"uint8"}],"name":"setStakingModuleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"}],"name":"setWithdrawalCredentials","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"bool","name":"_triggerUpdateFinish","type":"bool"},{"components":[{"internalType":"uint256","name":"currentModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOperatorExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOperatorStuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newNodeOperatorExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newNodeOperatorStuckValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.ValidatorsCountsCorrection","name":"_correction","type":"tuple"}],"name":"unsafeSetExitedValidatorsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_exitedValidatorsCounts","type":"uint256[]"}],"name":"updateExitedValidatorsCountByStakingModule","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"uint256","name":"_refundedValidatorsCount","type":"uint256"}],"name":"updateRefundedValidatorsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_targetShare","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"updateStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"bool","name":"_isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"_targetLimit","type":"uint256"}],"name":"updateTargetValidatorsLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_depositContract", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AppAuthLidoFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "firstArrayLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "secondArrayLength", + "type": "uint256" + } + ], + "name": "ArraysLengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "DepositContractZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DirectETHTransfer", + "type": "error" + }, + { + "inputs": [], + "name": "EmptyWithdrawalsCredentials", + "type": "error" + }, + { + "inputs": [], + "name": "ExitedValidatorsCountCannotDecrease", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidContractVersionIncrement", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "etherValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositsCount", + "type": "uint256" + } + ], + "name": "InvalidDepositsValue", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidFeeSum", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidMinDepositBlockDistance", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPriorityExitShareThreshold", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "actual", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + } + ], + "name": "InvalidPublicKeysBatchLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "code", + "type": "uint256" + } + ], + "name": "InvalidReportData", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "actual", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + } + ], + "name": "InvalidSignaturesBatchLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidStakeShareLimit", + "type": "error" + }, + { + "inputs": [], + "name": "NonZeroContractVersionOnInit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reportedExitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedValidatorsCount", + "type": "uint256" + } + ], + "name": "ReportedExitedValidatorsExceedDeposited", + "type": "error" + }, + { + "inputs": [], + "name": "StakingModuleAddressExists", + "type": "error" + }, + { + "inputs": [], + "name": "StakingModuleNotActive", + "type": "error" + }, + { + "inputs": [], + "name": "StakingModuleStatusTheSame", + "type": "error" + }, + { + "inputs": [], + "name": "StakingModuleUnregistered", + "type": "error" + }, + { + "inputs": [], + "name": "StakingModuleWrongName", + "type": "error" + }, + { + "inputs": [], + "name": "StakingModulesLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "UnexpectedContractVersion", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentModuleExitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentNodeOpExitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentNodeOpStuckValidatorsCount", + "type": "uint256" + } + ], + "name": "UnexpectedCurrentValidatorsCount", + "type": "error" + }, + { + "inputs": [], + "name": "UnrecoverableModuleError", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressAdmin", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressLido", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressStakingModule", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + } + ], + "name": "ContractVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "lowLevelRevertData", + "type": "bytes" + } + ], + "name": "ExitedAndStuckValidatorsCountsUpdateFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "lowLevelRevertData", + "type": "bytes" + } + ], + "name": "RewardsMintedReportFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "stakingModule", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "createdBy", + "type": "address" + } + ], + "name": "StakingModuleAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "unreportedExitedValidatorsCount", + "type": "uint256" + } + ], + "name": "StakingModuleExitedValidatorsIncompleteReporting", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stakingModuleFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "setBy", + "type": "address" + } + ], + "name": "StakingModuleFeesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxDepositsPerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "setBy", + "type": "address" + } + ], + "name": "StakingModuleMaxDepositsPerBlockSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "minDepositBlockDistance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "setBy", + "type": "address" + } + ], + "name": "StakingModuleMinDepositBlockDistanceSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stakeShareLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "priorityExitShareThreshold", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "setBy", + "type": "address" + } + ], + "name": "StakingModuleShareLimitSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum StakingRouter.StakingModuleStatus", + "name": "status", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "address", + "name": "setBy", + "type": "address" + } + ], + "name": "StakingModuleStatusSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "StakingRouterETHDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "withdrawalCredentials", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "setBy", + "type": "address" + } + ], + "name": "WithdrawalCredentialsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "lowLevelRevertData", + "type": "bytes" + } + ], + "name": "WithdrawalsCredentialsChangeFailed", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEPOSIT_CONTRACT", + "outputs": [ + { + "internalType": "contract IDepositContract", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_PRECISION_POINTS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_WITHDRAWAL_CREDENTIALS_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_STAKING_MODULES_COUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_STAKING_MODULE_NAME_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REPORT_EXITED_VALIDATORS_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REPORT_REWARDS_MINTED_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_MODULE_MANAGE_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_MODULE_UNVETTING_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOTAL_BASIS_POINTS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNSAFE_SET_EXITED_VALIDATORS_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "address", + "name": "_stakingModuleAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_stakeShareLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_priorityExitShareThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_stakingModuleFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_treasuryFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDepositsPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minDepositBlockDistance", + "type": "uint256" + } + ], + "name": "addStakingModule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_vettedSigningKeysCounts", + "type": "bytes" + } + ], + "name": "decreaseStakingModuleVettedKeysCountByNodeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_depositsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_depositCalldata", + "type": "bytes" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_priorityExitShareThresholds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "_maxDepositsPerBlock", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "_minDepositBlockDistances", + "type": "uint256[]" + } + ], + "name": "finalizeUpgrade_v2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getAllNodeOperatorDigests", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "targetLimitMode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "internalType": "struct StakingRouter.NodeOperatorSummary", + "name": "summary", + "type": "tuple" + } + ], + "internalType": "struct StakingRouter.NodeOperatorDigest[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllStakingModuleDigests", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nodeOperatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "activeNodeOperatorsCount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint24", + "name": "id", + "type": "uint24" + }, + { + "internalType": "address", + "name": "stakingModuleAddress", + "type": "address" + }, + { + "internalType": "uint16", + "name": "stakingModuleFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "treasuryFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "stakeShareLimit", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "status", + "type": "uint8" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint64", + "name": "lastDepositAt", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "lastDepositBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "priorityExitShareThreshold", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "maxDepositsPerBlock", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "minDepositBlockDistance", + "type": "uint64" + } + ], + "internalType": "struct StakingRouter.StakingModule", + "name": "state", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "internalType": "struct StakingRouter.StakingModuleSummary", + "name": "summary", + "type": "tuple" + } + ], + "internalType": "struct StakingRouter.StakingModuleDigest[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_depositsCount", + "type": "uint256" + } + ], + "name": "getDepositsAllocation", + "outputs": [ + { + "internalType": "uint256", + "name": "allocated", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "allocations", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLido", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_nodeOperatorIds", + "type": "uint256[]" + } + ], + "name": "getNodeOperatorDigests", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "targetLimitMode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "internalType": "struct StakingRouter.NodeOperatorSummary", + "name": "summary", + "type": "tuple" + } + ], + "internalType": "struct StakingRouter.NodeOperatorDigest[]", + "name": "digests", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_limit", + "type": "uint256" + } + ], + "name": "getNodeOperatorDigests", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "targetLimitMode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "internalType": "struct StakingRouter.NodeOperatorSummary", + "name": "summary", + "type": "tuple" + } + ], + "internalType": "struct StakingRouter.NodeOperatorDigest[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getNodeOperatorSummary", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "targetLimitMode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "internalType": "struct StakingRouter.NodeOperatorSummary", + "name": "summary", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingFeeAggregateDistribution", + "outputs": [ + { + "internalType": "uint96", + "name": "modulesFee", + "type": "uint96" + }, + { + "internalType": "uint96", + "name": "treasuryFee", + "type": "uint96" + }, + { + "internalType": "uint256", + "name": "basePrecision", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingFeeAggregateDistributionE4Precision", + "outputs": [ + { + "internalType": "uint16", + "name": "modulesFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "treasuryFee", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModule", + "outputs": [ + { + "components": [ + { + "internalType": "uint24", + "name": "id", + "type": "uint24" + }, + { + "internalType": "address", + "name": "stakingModuleAddress", + "type": "address" + }, + { + "internalType": "uint16", + "name": "stakingModuleFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "treasuryFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "stakeShareLimit", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "status", + "type": "uint8" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint64", + "name": "lastDepositAt", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "lastDepositBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "priorityExitShareThreshold", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "maxDepositsPerBlock", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "minDepositBlockDistance", + "type": "uint64" + } + ], + "internalType": "struct StakingRouter.StakingModule", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleActiveValidatorsCount", + "outputs": [ + { + "internalType": "uint256", + "name": "activeValidatorsCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_stakingModuleIds", + "type": "uint256[]" + } + ], + "name": "getStakingModuleDigests", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "nodeOperatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "activeNodeOperatorsCount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint24", + "name": "id", + "type": "uint24" + }, + { + "internalType": "address", + "name": "stakingModuleAddress", + "type": "address" + }, + { + "internalType": "uint16", + "name": "stakingModuleFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "treasuryFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "stakeShareLimit", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "status", + "type": "uint8" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint64", + "name": "lastDepositAt", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "lastDepositBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "priorityExitShareThreshold", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "maxDepositsPerBlock", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "minDepositBlockDistance", + "type": "uint64" + } + ], + "internalType": "struct StakingRouter.StakingModule", + "name": "state", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "internalType": "struct StakingRouter.StakingModuleSummary", + "name": "summary", + "type": "tuple" + } + ], + "internalType": "struct StakingRouter.StakingModuleDigest[]", + "name": "digests", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingModuleIds", + "outputs": [ + { + "internalType": "uint256[]", + "name": "stakingModuleIds", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleIsActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleIsDepositsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleIsStopped", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleLastDepositBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDepositsValue", + "type": "uint256" + } + ], + "name": "getStakingModuleMaxDepositsCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleMaxDepositsPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleMinDepositBlockDistance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleStatus", + "outputs": [ + { + "internalType": "enum StakingRouter.StakingModuleStatus", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "getStakingModuleSummary", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "internalType": "struct StakingRouter.StakingModuleSummary", + "name": "summary", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingModules", + "outputs": [ + { + "components": [ + { + "internalType": "uint24", + "name": "id", + "type": "uint24" + }, + { + "internalType": "address", + "name": "stakingModuleAddress", + "type": "address" + }, + { + "internalType": "uint16", + "name": "stakingModuleFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "treasuryFee", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "stakeShareLimit", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "status", + "type": "uint8" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint64", + "name": "lastDepositAt", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "lastDepositBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "priorityExitShareThreshold", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "maxDepositsPerBlock", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "minDepositBlockDistance", + "type": "uint64" + } + ], + "internalType": "struct StakingRouter.StakingModule[]", + "name": "res", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingModulesCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingRewardsDistribution", + "outputs": [ + { + "internalType": "address[]", + "name": "recipients", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "stakingModuleIds", + "type": "uint256[]" + }, + { + "internalType": "uint96[]", + "name": "stakingModuleFees", + "type": "uint96[]" + }, + { + "internalType": "uint96", + "name": "totalFee", + "type": "uint96" + }, + { + "internalType": "uint256", + "name": "precisionPoints", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalFeeE4Precision", + "outputs": [ + { + "internalType": "uint16", + "name": "totalFee", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWithdrawalCredentials", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + } + ], + "name": "hasStakingModule", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_lido", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_withdrawalCredentials", + "type": "bytes32" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "onValidatorsCountsByNodeOperatorReportingFinished", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_stakingModuleIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "_totalShares", + "type": "uint256[]" + } + ], + "name": "reportRewardsMinted", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_exitedValidatorsCounts", + "type": "bytes" + } + ], + "name": "reportStakingModuleExitedValidatorsCountByNodeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_stuckValidatorsCounts", + "type": "bytes" + } + ], + "name": "reportStakingModuleStuckValidatorsCountByNodeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "enum StakingRouter.StakingModuleStatus", + "name": "_status", + "type": "uint8" + } + ], + "name": "setStakingModuleStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_withdrawalCredentials", + "type": "bytes32" + } + ], + "name": "setWithdrawalCredentials", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_triggerUpdateFinish", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "currentModuleExitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentNodeOperatorExitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentNodeOperatorStuckValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newModuleExitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newNodeOperatorExitedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newNodeOperatorStuckValidatorsCount", + "type": "uint256" + } + ], + "internalType": "struct StakingRouter.ValidatorsCountsCorrection", + "name": "_correction", + "type": "tuple" + } + ], + "name": "unsafeSetExitedValidatorsCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_stakingModuleIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "_exitedValidatorsCounts", + "type": "uint256[]" + } + ], + "name": "updateExitedValidatorsCountByStakingModule", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_refundedValidatorsCount", + "type": "uint256" + } + ], + "name": "updateRefundedValidatorsCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_stakeShareLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_priorityExitShareThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_stakingModuleFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_treasuryFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxDepositsPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minDepositBlockDistance", + "type": "uint256" + } + ], + "name": "updateStakingModule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingModuleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_targetLimitMode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_targetLimit", + "type": "uint256" + } + ], + "name": "updateTargetValidatorsLimits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/interfaces/v3/DepositSecurityModuleV3.json b/interfaces/v3/DepositSecurityModuleV3.json index ed4961480..fce979394 100644 --- a/interfaces/v3/DepositSecurityModuleV3.json +++ b/interfaces/v3/DepositSecurityModuleV3.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"address","name":"_lido","type":"address"},{"internalType":"address","name":"_depositContract","type":"address"},{"internalType":"address","name":"_stakingRouter","type":"address"},{"internalType":"uint256","name":"_maxDepositsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_minDepositBlockDistance","type":"uint256"},{"internalType":"uint256","name":"_pauseIntentValidityPeriodBlocks","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DepositInactiveModule","type":"error"},{"inputs":[],"name":"DepositNoQuorum","type":"error"},{"inputs":[],"name":"DepositNonceChanged","type":"error"},{"inputs":[],"name":"DepositRootChanged","type":"error"},{"inputs":[],"name":"DepositTooFrequent","type":"error"},{"inputs":[],"name":"DepositUnexpectedBlockHash","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"DuplicateAddress","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotAGuardian","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotAnOwner","type":"error"},{"inputs":[],"name":"PauseIntentExpired","type":"error"},{"inputs":[],"name":"SignaturesNotSorted","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"inputs":[{"internalType":"string","name":"parameter","type":"string"}],"name":"ZeroParameter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"GuardianQuorumChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MaxDepositsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinDepositBlockDistanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"PauseIntentValidityPeriodBlocksChanged","type":"event"},{"inputs":[],"name":"ATTEST_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"contract ILido","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_ROUTER","outputs":[{"internalType":"contract IStakingRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardians","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"canDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"depositCalldata","type":"bytes"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature[]","name":"sortedGuardianSignatures","type":"tuple[]"}],"name":"depositBufferedEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getGuardianIndex","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardianQuorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardians","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinDepositBlockDistance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseIntentValidityPeriodBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature","name":"sig","type":"tuple"}],"name":"pauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"removeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setGuardianQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMaxDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMinDepositBlockDistance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setPauseIntentValidityPeriodBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"unpauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"}]s \ No newline at end of file +[{"inputs":[{"internalType":"address","name":"_lido","type":"address"},{"internalType":"address","name":"_depositContract","type":"address"},{"internalType":"address","name":"_stakingRouter","type":"address"},{"internalType":"uint256","name":"_maxDepositsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_minDepositBlockDistance","type":"uint256"},{"internalType":"uint256","name":"_pauseIntentValidityPeriodBlocks","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DepositInactiveModule","type":"error"},{"inputs":[],"name":"DepositNoQuorum","type":"error"},{"inputs":[],"name":"DepositNonceChanged","type":"error"},{"inputs":[],"name":"DepositRootChanged","type":"error"},{"inputs":[],"name":"DepositTooFrequent","type":"error"},{"inputs":[],"name":"DepositUnexpectedBlockHash","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"DuplicateAddress","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotAGuardian","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotAnOwner","type":"error"},{"inputs":[],"name":"PauseIntentExpired","type":"error"},{"inputs":[],"name":"SignaturesNotSorted","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"inputs":[{"internalType":"string","name":"parameter","type":"string"}],"name":"ZeroParameter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"GuardianQuorumChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MaxDepositsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinDepositBlockDistanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"PauseIntentValidityPeriodBlocksChanged","type":"event"},{"inputs":[],"name":"ATTEST_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"contract ILido","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_ROUTER","outputs":[{"internalType":"contract IStakingRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardians","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"canDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"depositCalldata","type":"bytes"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature[]","name":"sortedGuardianSignatures","type":"tuple[]"}],"name":"depositBufferedEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getGuardianIndex","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardianQuorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardians","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinDepositBlockDistance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseIntentValidityPeriodBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature","name":"sig","type":"tuple"}],"name":"pauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"removeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setGuardianQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMaxDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMinDepositBlockDistance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setPauseIntentValidityPeriodBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"unpauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/scripts/staking_router_v2_holesky.py b/scripts/staking_router_v2_holesky.py index b91fd840a..9e5a8e2cf 100644 --- a/scripts/staking_router_v2_holesky.py +++ b/scripts/staking_router_v2_holesky.py @@ -17,9 +17,17 @@ import time +try: + from brownie import interface, accounts +except ImportError: + print("You're probably running inside Brownie console. Please call:") + print("set_console_globals(interface=interface)") + + from typing import Dict, Tuple, Optional from utils.config import ( get_deployer_account, + get_is_live, contracts, LIDO_LOCATOR, LIDO_LOCATOR_IMPL, @@ -46,47 +54,47 @@ PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000] MAX_DEPOSITS_PER_BLOCK = [50] MIN_DEPOSIT_BLOCK_DISTANCES = [25] -NOR_CONTENT_URI = "0x" + "00".repeat(51) # ? +NOR_CONTENT_URI = "0x" + "00" * 51 # ? NOR_VERSION = ["2", "0", "0"] NOR_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" AO_CONSENSUS_VERSION = 2 VEBO_CONSENSUS_VERSION = 2 -def encode_locator_proxy_update(locator_proxy_address: str, implementation: str) -> Tuple[str, str]: - proxy = interface.LidoLocator(locator_proxy_address) - return proxy.address, proxy.proxy_upgradeTo.encode_input(implementation, b"") +def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.lido_locator) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) -def encode_staking_router_proxy_update(sr_proxy_address: str, implementation: str) -> Tuple[str, str]: - proxy = interface.StakingRouter(sr_proxy_address) - return proxy.address, proxy.proxy_upgradeTo.encode_input(implementation, b"") +def encode_staking_router_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.staking_router) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) -def encode_staking_router_finalize(sr_proxy_address: str) -> Tuple[str, str]: - proxy = interface.StakingRouter(sr_proxy_address) +def encode_staking_router_finalize() -> Tuple[str, str]: + proxy = interface.StakingRouter(contracts.staking_router) return proxy.address, proxy.finalizeUpgrade_v2.encode_input( PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES ) -def encode_nor_finalize(nor_address: str) -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(nor_address) +def encode_nor_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.node_operators_registry) return proxy.address, proxy.finalizeUpgrade_v3.encode_input() -def encode_ao_proxy_update(ao_proxy: str, implementation: str) -> Tuple[str, str]: - proxy = interface.AccountingOracle(ao_proxy) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation, b"") +def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.accounting_oracle) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) -def encode_ao_finalize(ao: str) -> Tuple[str, str]: - proxy = interface.AccountingOracle(ao) +def encode_ao_finalize() -> Tuple[str, str]: + proxy = interface.AccountingOracle(contracts.accounting_oracle) return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) def encode_set_consensus_version(vebo: str) -> Tuple[str, str]: - proxy = interface.ValidatorExitBusOracle(vebo) + proxy = interface.ValidatorsExitBusOracle(vebo) return proxy.address, proxy.setConsensusVersion(vebo) @@ -95,7 +103,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T call_script_items = [ # 1) - encode_locator_proxy_update(LIDO_LOCATOR, LIDO_LOCATOR_IMPL), + encode_locator_proxy_update(LIDO_LOCATOR_IMPL), # 2) encode_permission_revoke( contracts.staking_router, "STAKING_MODULE_PAUSE_ROLE", revoke_from=contracts.deposit_security_module @@ -111,19 +119,19 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T permission_name="STAKING_MODULE_UNVETTING_ROLE", ), # 5) - encode_staking_router_proxy_update(STAKING_ROUTER, STAKING_ROUTER_IMPL), + encode_staking_router_proxy_update(STAKING_ROUTER_IMPL), # 6) - encode_staking_router_finalize(STAKING_ROUTER), + encode_staking_router_finalize(), # 7) add_implementation_to_nor_app_repo(NOR_VERSION, NOR_IMPL, NOR_CONTENT_URI), # 8) update_app_implementation(NOR_APP_ID, NOR_IMPL), # 9) - encode_nor_finalize(NODE_OPERATORS_REGISTRY), + encode_nor_finalize(), # 10) - encode_ao_proxy_update(ACCOUNTING_ORACLE, ACCOUNTING_ORACLE_IMPL), + encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL), # 11) - encode_ao_finalize(ACCOUNTING_ORACLE), + encode_ao_finalize(), # 12) encode_permission_grant( grant_to=VALIDATORS_EXIT_BUS_ORACLE, From e0c69ee9612c83fa5a80fd6b006d8df3aa36bbfd Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 14 Jun 2024 17:42:23 +0400 Subject: [PATCH 003/220] fix: forwarding via agent locator upgrade --- configs/config_holesky.py | 12 +-- scripts/staking_router_v2_holesky.py | 106 ++++++++++++++------------- 2 files changed, 61 insertions(+), 57 deletions(-) diff --git a/configs/config_holesky.py b/configs/config_holesky.py index 934c8b730..bf07a6bc7 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -23,7 +23,7 @@ LIDO = "0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034" LEGACY_ORACLE = "0x072f72BE3AcFE2c52715829F2CD9061A6C8fF019" NODE_OPERATORS_REGISTRY = "0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" -NOR_IMPL = "0x0c626FC4A447b01554518550e30600136864640B" # set address here after deploy +NOR_IMPL = "0x4d75529C753eef6e18F2D37D13508FC5035Ec95e" # set address here after deploy # Aragon APM Repos VOTING_REPO = "0x2997EA0D07D79038D83Cb04b3BB9A2Bc512E3fDA" @@ -78,20 +78,20 @@ # LIDO_LOCATOR = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -LIDO_LOCATOR_IMPL = "0x2F54D1563963fC04770E85AF819c89Dc807f6a06" # set address here after deploy +LIDO_LOCATOR_IMPL = "0xdcc2dD90186602f29Dfb0C8A65c9BD4d237090Ed" # set address here after deploy WITHDRAWAL_QUEUE = "0xc7cc160b58F8Bb0baC94b80847E2CF2800565C50" ORACLE_DAEMON_CONFIG = "0xC01fC1F2787687Bc656EAc0356ba9Db6e6b7afb7" ORACLE_REPORT_SANITY_CHECKER = "0xF0d576c7d934bBeCc68FE15F1c5DAF98ea2B78bb" -ORACLE_REPORT_SANITY_CHECKER_V2 = "0x158d291D8b47F056751cfF47d1eEcd19FDF9B6f8" # should be changed for new +ORACLE_REPORT_SANITY_CHECKER_V2 = "0x7A4D8dF25f2A43505940232aC1397235899Fa8C" # should be changed for new BURNER = "0x4E46BD7147ccf666E1d73A3A456fC7a68de82eCA" DEPOSIT_SECURITY_MODULE = "0x045dd46212A178428c088573A7d102B9d89a022A" -DEPOSIT_SECURITY_MODULE_V3 = "0xA21DDc1f17dF41589BC6A5209292AED2dF61Cc94" # set address here after deploy +DEPOSIT_SECURITY_MODULE_V3 = "0x389D2352b39962cE98D990a979639C1E07ed500f" # set address here after deploy ACCOUNTING_ORACLE = "0x4E97A3972ce8511D87F334dA17a2C332542a5246" -ACCOUNTING_ORACLE_IMPL = "0x2A590C461Db46bca129E8dBe5C3998A8fF402e76" # set address here after deploy +ACCOUNTING_ORACLE_IMPL = "0xFA6DD77332A32858f472c423d7fA79b99EEF386c" # set address here after deploy VALIDATORS_EXIT_BUS_ORACLE = "0xffDDF7025410412deaa05E3E1cE68FE53208afcb" EIP712_STETH = "0xE154732c5Eab277fd88a9fF6Bdff7805eD97BCB1" STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" -STAKING_ROUTER_IMPL = "0x33E45b187da34826aBCEDA1039231Be46f1b05Af" # set address here after deploy +STAKING_ROUTER_IMPL = "0x38CE89269bF7145769a867F355B492a867e26Ab5" # set address here after deploy WITHDRAWAL_VAULT_IMPL = "0xd517d9d04DA9B47dA23df91261bd3bF435BE964A" diff --git a/scripts/staking_router_v2_holesky.py b/scripts/staking_router_v2_holesky.py index 9e5a8e2cf..42bbc770f 100644 --- a/scripts/staking_router_v2_holesky.py +++ b/scripts/staking_router_v2_holesky.py @@ -49,6 +49,7 @@ from utils.voting import bake_vote_items, confirm_vote_script, create_vote from brownie.network.transaction import TransactionReceipt +from utils.agent import agent_forward PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000] @@ -63,6 +64,8 @@ def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: proxy = interface.OssifiableProxy(contracts.lido_locator) + print(f"locator implementation {implementation}") + print(f"proxy {proxy.address}") return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) @@ -95,7 +98,7 @@ def encode_ao_finalize() -> Tuple[str, str]: def encode_set_consensus_version(vebo: str) -> Tuple[str, str]: proxy = interface.ValidatorsExitBusOracle(vebo) - return proxy.address, proxy.setConsensusVersion(vebo) + return proxy.address, proxy.setConsensusVersion.encode_input(vebo) def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: @@ -103,59 +106,59 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T call_script_items = [ # 1) - encode_locator_proxy_update(LIDO_LOCATOR_IMPL), + agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), # 2) - encode_permission_revoke( - contracts.staking_router, "STAKING_MODULE_PAUSE_ROLE", revoke_from=contracts.deposit_security_module - ), - # 3) - encode_permission_revoke( - contracts.staking_router, "STAKING_MODULE_RESUME_ROLE", revoke_from=contracts.deposit_security_module - ), - # 4) - encode_permission_grant( - grant_to=contracts.deposit_security_module_v3, - target_app=contracts.staking_router, - permission_name="STAKING_MODULE_UNVETTING_ROLE", - ), - # 5) - encode_staking_router_proxy_update(STAKING_ROUTER_IMPL), - # 6) - encode_staking_router_finalize(), - # 7) - add_implementation_to_nor_app_repo(NOR_VERSION, NOR_IMPL, NOR_CONTENT_URI), - # 8) - update_app_implementation(NOR_APP_ID, NOR_IMPL), - # 9) - encode_nor_finalize(), - # 10) - encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL), - # 11) - encode_ao_finalize(), - # 12) - encode_permission_grant( - grant_to=VALIDATORS_EXIT_BUS_ORACLE, - target_app=AGENT, # ??? - permission_name="MANAGE_CONSENSUS_VERSION_ROLE", - ), - # 13) - encode_set_consensus_version(VALIDATORS_EXIT_BUS_ORACLE), + # encode_permission_revoke( + # contracts.staking_router, "STAKING_MODULE_PAUSE_ROLE", revoke_from=contracts.deposit_security_module + # ), + # # 3) + # encode_permission_revoke( + # contracts.staking_router, "STAKING_MODULE_RESUME_ROLE", revoke_from=contracts.deposit_security_module + # ), + # # 4) + # encode_permission_grant( + # grant_to=contracts.deposit_security_module_v3, + # target_app=contracts.staking_router, + # permission_name="STAKING_MODULE_UNVETTING_ROLE", + # ), + # # 5) + # encode_staking_router_proxy_update(STAKING_ROUTER_IMPL), + # # 6) + # encode_staking_router_finalize(), + # # 7) + # add_implementation_to_nor_app_repo(NOR_VERSION, NOR_IMPL, NOR_CONTENT_URI), + # # 8) + # update_app_implementation(NOR_APP_ID, NOR_IMPL), + # # 9) + # encode_nor_finalize(), + # # 10) + # encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL), + # # 11) + # encode_ao_finalize(), + # # 12) + # encode_permission_grant( + # grant_to=VALIDATORS_EXIT_BUS_ORACLE, + # target_app=AGENT, # ??? + # permission_name="MANAGE_CONSENSUS_VERSION_ROLE", + # ), + # # 13) + # encode_set_consensus_version(VALIDATORS_EXIT_BUS_ORACLE), ] vote_desc_items = [ "1. Update locator implementation", - "2. Revoke pause role from old DSM", - "3. Revoke resume role from old DSM", - "4. Grant unvetting role to new DSM", - "5. Update SR implementation", - "6. Call finalize upgrade on SR", - "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", - "8. Update `NodeOperatorsRegistry` implementation", - "9. Finalize NOR upgrade", - "10. Update AO implementation to ${AO_IMPLEMENTATION}", - "11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - "12. Grant manage consensus role to agent ${aragonAgentAddress}", - "13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + # "2. Revoke pause role from old DSM", + # "3. Revoke resume role from old DSM", + # "4. Grant unvetting role to new DSM", + # "5. Update SR implementation", + # "6. Call finalize upgrade on SR", + # "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + # "8. Update `NodeOperatorsRegistry` implementation", + # "9. Finalize NOR upgrade", + # "10. Update AO implementation to ${AO_IMPLEMENTATION}", + # "11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + # "12. Grant manage consensus role to agent ${aragonAgentAddress}", + # "13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", ] vote_items = bake_vote_items(vote_desc_items, call_script_items) @@ -166,13 +169,14 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T def main(): tx_params = {"from": get_deployer_account()} - # ???? if get_is_live(): tx_params["max_fee"] = "300 gwei" tx_params["priority_fee"] = "2 gwei" + print(tx_params) + vote_id, _ = start_vote(tx_params=tx_params, silent=False) vote_id >= 0 and print(f"Vote created: {vote_id}.") - time.sleep(5) # hack for waiting thread #2. + time.sleep(15) # hack for waiting thread #2. From 6ed7eae615656c3328d5dfae264225acbe77ad67 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 14 Jun 2024 20:30:31 +0400 Subject: [PATCH 004/220] fix: voting sr 2 script --- scripts/check.sh | 70 ++++++++++++++ scripts/staking_router_v2_holesky.py | 136 ++++++++++++++++----------- 2 files changed, 153 insertions(+), 53 deletions(-) create mode 100755 scripts/check.sh diff --git a/scripts/check.sh b/scripts/check.sh new file mode 100755 index 000000000..f92f68b5b --- /dev/null +++ b/scripts/check.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Set RPC URL +RPC_URL="http://127.0.0.1:8555" + +# Locator address +LOCATOR_ADDRESS="0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" +echo "Locator Address:" +cast call --rpc-url $RPC_URL $LOCATOR_ADDRESS "proxy__getImplementation()" --trace + +# Staking router implementation +STAKING_ROUTER="0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" +echo "Staking Router Implementation:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "proxy__getImplementation()" --trace + +# Pause role +PAUSE_ROLE="0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" +ADDRESS1="0x045dd46212A178428c088573A7d102B9d89a022A" +echo "Pause Role:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $PAUSE_ROLE $ADDRESS1 --trace + +# Resume role +RESUME_ROLE="0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" +echo "Resume Role:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $RESUME_ROLE $ADDRESS1 --trace + +# Unvetting role +UNVETTING_ROLE="0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" +ADDRESS2="0x389D2352b39962cE98D990a979639C1E07ed500f" +echo "Unvetting Role:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $UNVETTING_ROLE $ADDRESS2 --trace + +# SR version + +echo "staking router version:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "getContractVersion()(uint256)" --trace + + +# nor implementation was changed + +NOR="0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" + +echo "nor implemertation was changed" +cast call --rpc-url $RPC_URL $NOR "implementation()" --trace + +# nor version +echo "not version" +cast call --rpc-url $RPC_URL $NOR "getContractVersion()(uint256)" --trace + +# ao impl +AO=0x4E97A3972ce8511D87F334dA17a2C332542a5246 +echo "ao implementation" +cast call --rpc-url $RPC_URL $AO "proxy__getImplementation()" --trace + +echo "ao version" +cast call --rpc-url $RPC_URL $AO "getContractVersion()(uint256)" --trace + + +# vebo has MANAGE_CONSENSUS_VERSION_ROLE role + +MANAGE_CONSENSUS_VERSION_ROLE="0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" +VALIDATORS_EXIT_BUS_ORACLE="0xffDDF7025410412deaa05E3E1cE68FE53208afcb" +AGENT="0xE92329EC7ddB11D25e25b3c21eeBf11f15eB325d" +echo "vebo has MANAGE_CONSENSUS_VERSION_ROLE role:" +cast call --rpc-url $RPC_URL $VALIDATORS_EXIT_BUS_ORACLE "hasRole(bytes32,address)(bool)" $MANAGE_CONSENSUS_VERSION_ROLE $AGENT --trace + + +echo "VEBO getConsensusVersion" +cast call --rpc-url $RPC_URL $VALIDATORS_EXIT_BUS_ORACLE "getConsensusVersion()(uint256)" --trace + diff --git a/scripts/staking_router_v2_holesky.py b/scripts/staking_router_v2_holesky.py index 42bbc770f..051c40072 100644 --- a/scripts/staking_router_v2_holesky.py +++ b/scripts/staking_router_v2_holesky.py @@ -52,9 +52,9 @@ from utils.agent import agent_forward -PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000] -MAX_DEPOSITS_PER_BLOCK = [50] -MIN_DEPOSIT_BLOCK_DISTANCES = [25] +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] +MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] +MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] NOR_CONTENT_URI = "0x" + "00" * 51 # ? NOR_VERSION = ["2", "0", "0"] NOR_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" @@ -64,8 +64,6 @@ def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: proxy = interface.OssifiableProxy(contracts.lido_locator) - print(f"locator implementation {implementation}") - print(f"proxy {proxy.address}") return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) @@ -96,9 +94,9 @@ def encode_ao_finalize() -> Tuple[str, str]: return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) -def encode_set_consensus_version(vebo: str) -> Tuple[str, str]: - proxy = interface.ValidatorsExitBusOracle(vebo) - return proxy.address, proxy.setConsensusVersion.encode_input(vebo) +def encode_set_consensus_version() -> Tuple[str, str]: + proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) + return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: @@ -108,57 +106,89 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # 1) agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), # 2) - # encode_permission_revoke( - # contracts.staking_router, "STAKING_MODULE_PAUSE_ROLE", revoke_from=contracts.deposit_security_module - # ), - # # 3) - # encode_permission_revoke( - # contracts.staking_router, "STAKING_MODULE_RESUME_ROLE", revoke_from=contracts.deposit_security_module - # ), - # # 4) - # encode_permission_grant( - # grant_to=contracts.deposit_security_module_v3, - # target_app=contracts.staking_router, - # permission_name="STAKING_MODULE_UNVETTING_ROLE", - # ), - # # 5) - # encode_staking_router_proxy_update(STAKING_ROUTER_IMPL), - # # 6) - # encode_staking_router_finalize(), + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.revokeRole.encode_input( + # keccak256 STAKING_MODULE_PAUSE_ROLE + "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", + contracts.deposit_security_module, + ), + ) + ] + ), + # 3) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.revokeRole.encode_input( + # keccak256 STAKING_MODULE_RESUME_ROLE + "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", + contracts.deposit_security_module, + ), + ) + ] + ), + # 4) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.grantRole.encode_input( + # keccak256 STAKING_MODULE_UNVETTING_ROLE + "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", + contracts.deposit_security_module_v3, + ), + ) + ] + ), + # 5) + agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), + # 6) + encode_staking_router_finalize(), # # 7) - # add_implementation_to_nor_app_repo(NOR_VERSION, NOR_IMPL, NOR_CONTENT_URI), + add_implementation_to_nor_app_repo(NOR_VERSION, NOR_IMPL, NOR_CONTENT_URI), # # 8) - # update_app_implementation(NOR_APP_ID, NOR_IMPL), + update_app_implementation(NOR_APP_ID, NOR_IMPL), # # 9) - # encode_nor_finalize(), - # # 10) - # encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL), - # # 11) - # encode_ao_finalize(), - # # 12) - # encode_permission_grant( - # grant_to=VALIDATORS_EXIT_BUS_ORACLE, - # target_app=AGENT, # ??? - # permission_name="MANAGE_CONSENSUS_VERSION_ROLE", - # ), - # # 13) - # encode_set_consensus_version(VALIDATORS_EXIT_BUS_ORACLE), + encode_nor_finalize(), + # 10) + agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + # 11) + encode_ao_finalize(), + # 12) + agent_forward( + [ + ( + contracts.validators_exit_bus_oracle.address, + contracts.validators_exit_bus_oracle.grantRole.encode_input( + # keccak256 MANAGE_CONSENSUS_VERSION_ROLE + "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", + AGENT, + ), + ) + ] + ), + # 13) + agent_forward([encode_set_consensus_version()]), ] vote_desc_items = [ "1. Update locator implementation", - # "2. Revoke pause role from old DSM", - # "3. Revoke resume role from old DSM", - # "4. Grant unvetting role to new DSM", - # "5. Update SR implementation", - # "6. Call finalize upgrade on SR", - # "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", - # "8. Update `NodeOperatorsRegistry` implementation", - # "9. Finalize NOR upgrade", - # "10. Update AO implementation to ${AO_IMPLEMENTATION}", - # "11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - # "12. Grant manage consensus role to agent ${aragonAgentAddress}", - # "13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + "2. Revoke pause role from old DSM", + "3. Revoke resume role from old DSM", + "4. Grant unvetting role to new DSM", + "5. Update SR implementation", + "6. Call finalize upgrade on SR", + "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + "8. Update `NodeOperatorsRegistry` implementation", + "9. Finalize NOR upgrade", + "10. Update AO implementation to ${AO_IMPLEMENTATION}", + "11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + "12. Grant manage consensus role to agent ${aragonAgentAddress}", + "13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", ] vote_items = bake_vote_items(vote_desc_items, call_script_items) @@ -179,4 +209,4 @@ def main(): vote_id >= 0 and print(f"Vote created: {vote_id}.") - time.sleep(15) # hack for waiting thread #2. + time.sleep(5) # hack for waiting thread #2. From 1c269a503045da274fcb06a24dfc2fe387749e28 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 17 Jun 2024 14:20:08 +0400 Subject: [PATCH 005/220] fix: small fixes --- scripts/scripts.code-workspace | 18 ------------------ scripts/staking_router_v2_holesky.py | 11 +++-------- 2 files changed, 3 insertions(+), 26 deletions(-) delete mode 100644 scripts/scripts.code-workspace diff --git a/scripts/scripts.code-workspace b/scripts/scripts.code-workspace deleted file mode 100644 index 3f9c93ccd..000000000 --- a/scripts/scripts.code-workspace +++ /dev/null @@ -1,18 +0,0 @@ -{ - "folders": [ - { - "path": ".." - }, - { - "path": "../../core" - }, - { - "path": "../../lido-cli" - } -], - "settings": { - "[json]": { - "editor.formatOnSave": false - } - } -} diff --git a/scripts/staking_router_v2_holesky.py b/scripts/staking_router_v2_holesky.py index 051c40072..7b8487666 100644 --- a/scripts/staking_router_v2_holesky.py +++ b/scripts/staking_router_v2_holesky.py @@ -29,15 +29,10 @@ get_deployer_account, get_is_live, contracts, - LIDO_LOCATOR, LIDO_LOCATOR_IMPL, - STAKING_ROUTER, STAKING_ROUTER_IMPL, - NODE_OPERATORS_REGISTRY, NOR_IMPL, - ACCOUNTING_ORACLE, ACCOUNTING_ORACLE_IMPL, - VALIDATORS_EXIT_BUS_ORACLE, AGENT, ) from utils.permissions import encode_permission_revoke, encode_permission_grant @@ -148,11 +143,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), # 6) encode_staking_router_finalize(), - # # 7) + # 7) add_implementation_to_nor_app_repo(NOR_VERSION, NOR_IMPL, NOR_CONTENT_URI), - # # 8) + # 8) update_app_implementation(NOR_APP_ID, NOR_IMPL), - # # 9) + # 9) encode_nor_finalize(), # 10) agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), From d2b1d8ad96c83e2fe9c739b341af465a07ce5897 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 17 Jun 2024 19:26:10 +0400 Subject: [PATCH 006/220] fix: rename sr vote script --- ...staking_router_v2_holesky.py => vote_sr_v2_holesky.py} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename scripts/{staking_router_v2_holesky.py => vote_sr_v2_holesky.py} (96%) diff --git a/scripts/staking_router_v2_holesky.py b/scripts/vote_sr_v2_holesky.py similarity index 96% rename from scripts/staking_router_v2_holesky.py rename to scripts/vote_sr_v2_holesky.py index 7b8487666..8eba6658e 100644 --- a/scripts/staking_router_v2_holesky.py +++ b/scripts/vote_sr_v2_holesky.py @@ -9,9 +9,9 @@ 7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo 8. Update `NodeOperatorsRegistry` implementation 9. Finalize NOR upgrade -10. Update AO implementation to ${AO_IMPLEMENTATION}`, +10. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, 11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, -12. Grant manage consensus role to agent ${aragonAgentAddress}` +12. Grant manage consensus role to agent ${AGENT}` 13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` """ @@ -180,9 +180,9 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", "8. Update `NodeOperatorsRegistry` implementation", "9. Finalize NOR upgrade", - "10. Update AO implementation to ${AO_IMPLEMENTATION}", + "10. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", "11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - "12. Grant manage consensus role to agent ${aragonAgentAddress}", + "12. Grant manage consensus role to agent ${AGENT}", "13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", ] From 9217b845fe84ab66b9a0a58a4a60b6972eddebf9 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 20 Jun 2024 04:04:35 +0400 Subject: [PATCH 007/220] fix: temp version --- configs/config_holesky.py | 28 +- configs/config_mainnet.py | 18 +- interfaces/DepositSecurityModule.json | 462 ++++++++++++++++++++- interfaces/Sandbox.json | 1 + interfaces/v3/DepositSecurityModuleV3.json | 1 - scripts/helpers/check.sh | 70 ++++ scripts/helpers/check_holesky.py | 77 ++++ scripts/helpers/check_mainnet.py | 69 +++ scripts/helpers/exec_voting.py | 68 +++ scripts/helpers/impersonate.py | 10 + scripts/vote_sr_v2_holesky.py | 113 ++++- scripts/vote_sr_v2_mainnet.py | 255 ++++++++++++ utils/config.py | 16 +- utils/repo.py | 8 + 14 files changed, 1156 insertions(+), 40 deletions(-) create mode 100644 interfaces/Sandbox.json delete mode 100644 interfaces/v3/DepositSecurityModuleV3.json create mode 100755 scripts/helpers/check.sh create mode 100644 scripts/helpers/check_holesky.py create mode 100644 scripts/helpers/check_mainnet.py create mode 100644 scripts/helpers/exec_voting.py create mode 100644 scripts/helpers/impersonate.py create mode 100644 scripts/vote_sr_v2_mainnet.py diff --git a/configs/config_holesky.py b/configs/config_holesky.py index bf07a6bc7..3f226b4bf 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -23,7 +23,8 @@ LIDO = "0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034" LEGACY_ORACLE = "0x072f72BE3AcFE2c52715829F2CD9061A6C8fF019" NODE_OPERATORS_REGISTRY = "0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" -NOR_IMPL = "0x4d75529C753eef6e18F2D37D13508FC5035Ec95e" # set address here after deploy +# set address here after deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x6951b5Bd815043E3F842c1b026b0Fa888Cc2DD85" # Aragon APM Repos VOTING_REPO = "0x2997EA0D07D79038D83Cb04b3BB9A2Bc512E3fDA" @@ -76,22 +77,21 @@ WETH_TOKEN = "" -# LIDO_LOCATOR = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -LIDO_LOCATOR_IMPL = "0xdcc2dD90186602f29Dfb0C8A65c9BD4d237090Ed" # set address here after deploy +LIDO_LOCATOR_IMPL = "0xcCB53c9429d32594F404d01fbe9E65ED1DCda8D9" # set address here after deploy WITHDRAWAL_QUEUE = "0xc7cc160b58F8Bb0baC94b80847E2CF2800565C50" ORACLE_DAEMON_CONFIG = "0xC01fC1F2787687Bc656EAc0356ba9Db6e6b7afb7" -ORACLE_REPORT_SANITY_CHECKER = "0xF0d576c7d934bBeCc68FE15F1c5DAF98ea2B78bb" -ORACLE_REPORT_SANITY_CHECKER_V2 = "0x7A4D8dF25f2A43505940232aC1397235899Fa8C" # should be changed for new +ORACLE_REPORT_SANITY_CHECKER = "0x7A4D8dF25f2A43505940232aC1397235899Fa8C" # should be changed for new + BURNER = "0x4E46BD7147ccf666E1d73A3A456fC7a68de82eCA" -DEPOSIT_SECURITY_MODULE = "0x045dd46212A178428c088573A7d102B9d89a022A" -DEPOSIT_SECURITY_MODULE_V3 = "0x389D2352b39962cE98D990a979639C1E07ed500f" # set address here after deploy +DEPOSIT_SECURITY_MODULE = "0xe0aA552A10d7EC8760Fc6c246D391E698a82dDf9" # dsm address after SR V2 +DEPOSIT_SECURITY_MODULE_V2 = "0x045dd46212A178428c088573A7d102B9d89a022A" # dsm address before SR V2 enact ACCOUNTING_ORACLE = "0x4E97A3972ce8511D87F334dA17a2C332542a5246" -ACCOUNTING_ORACLE_IMPL = "0xFA6DD77332A32858f472c423d7fA79b99EEF386c" # set address here after deploy +ACCOUNTING_ORACLE_IMPL = "0x6b4BDe1086912A6Cb24ce3dB43b3466e6c72AFd3" # set address here after SR V2 deploy VALIDATORS_EXIT_BUS_ORACLE = "0xffDDF7025410412deaa05E3E1cE68FE53208afcb" EIP712_STETH = "0xE154732c5Eab277fd88a9fF6Bdff7805eD97BCB1" STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" -STAKING_ROUTER_IMPL = "0x38CE89269bF7145769a867F355B492a867e26Ab5" # set address here after deploy +STAKING_ROUTER_IMPL = "0xE7eD6747FaC5360f88a2EFC03E00d25789F69291" # set address here after SR V2 deploy WITHDRAWAL_VAULT_IMPL = "0xd517d9d04DA9B47dA23df91261bd3bF435BE964A" @@ -101,3 +101,13 @@ GATE_SEAL_PAUSE_DURATION = 518400 # 6 days GATE_SEAL_EXPIRY_TIMESTAMP = 1714521600 # 2024-05-01 00:00GMT GATE_SEAL_COMMITTEE = "0x6165267E76D609465640bffc158aff7905D47B46" + + +NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" + +SIMPLE_DVT = "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6" +SIMPLE_DVT_REPO = "0x889dB59baf032E1dfD4fCA720e0833c24f1404C6" + + +SANDBOX = "0xD6C2ce3BB8bea2832496Ac8b5144819719f343AC" +SANDBOX_REPO = "0x00E75B5527a876B3F10C23436a0b896C626812d0" diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 976786d9c..6ceedfb28 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -27,7 +27,7 @@ LIDO_IMPL_V1 = "0x47EbaB13B806773ec2A2d16873e2dF770D130b50" LEGACY_ORACLE_IMPL_V1 = "0x1430194905301504e8830ce4B0b0df7187E84AbD" -NODE_OPERATORS_REGISTRY_IMPL_V1 = "0x5d39ABaa161e622B99D45616afC8B837E9F19a25" +NODE_OPERATORS_REGISTRY_IMPL_V1 = "0x5d39ABaa161e622B99D45616afC8B837E9F19a25" # was used in archived tests # Aragon APM Repos REPO_APP_ID = "0xbe49cbb8894efb45c933fd09dc87bdd94909553a9e1f511d7fc10f3dad1564f2" @@ -98,7 +98,7 @@ # LidoLocator LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" +LIDO_LOCATOR_IMPL = "0x832698Daec363C9A7aB036C224Af5B21280b3AC6" # set address here after SR V2 deploy # Other upgrade addresses LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" @@ -123,7 +123,7 @@ ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" # NodeOperatorsRegistry aka Curated Staking Module -NODE_OPERATORS_REGISTRY_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" +NODE_OPERATORS_REGISTRY_IMPL = "0x4D1B781ce59B8C184F63B99D39d6719A522f46B5" # set address after SR V2 deploy ## see NodeOperatorsRegistry's proxy appId() NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY = 432000 @@ -141,6 +141,7 @@ # NodeOperatorsRegistry clone aka SimpleDVT SIMPLE_DVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" +SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" ## see SimpleDVT's proxy appId() SIMPLE_DVT_ARAGON_APP_NAME = "simple-dvt" SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" @@ -168,7 +169,7 @@ FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT = 1350 # 6 days # OracleReportSanityChecker -ORACLE_REPORT_SANITY_CHECKER = "0x9305c1Dbfe22c12c66339184C0025d7006f0f1cC" +ORACLE_REPORT_SANITY_CHECKER = "0x2e13f7644014F6E934E314F0371585845de7B986" CHURN_VALIDATORS_PER_DAY_LIMIT = 20000 ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT = 500 # 5% ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% @@ -185,7 +186,8 @@ TOTAL_COVER_SHARES_BURNT = 0 # DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" +DEPOSIT_SECURITY_MODULE = "0xf9C8Cf55f2E520B08d869df7bc76aa3d3ddDF913" # dsm address after SR V2 enact +DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact DSM_MAX_DEPOSITS_PER_BLOCK = 150 DSM_MIN_DEPOSIT_BLOCK_DISTANCE = 25 DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS = 6646 @@ -203,7 +205,7 @@ # AccountingOracle # and its corresponding HashConsensus ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" +ACCOUNTING_ORACLE_IMPL = "0x654f70d8442EA18904FA1AD79114f7250F7E9336" # set address here after SR V2 deploy HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 @@ -250,7 +252,7 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" -STAKING_ROUTER_IMPL = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" +STAKING_ROUTER_IMPL = "0xD22363efee93190f82b52FCD62B7Dbcb920eF658" # set address here after deploy # Not a precise but still some estimation of the fees. Assume here that both modules are filled # SR_MODULES_FEE = curated_module_fee * (100% - sdvt_module_share) + sdvt_module_fee * sdvt_module_share @@ -300,3 +302,5 @@ # Rewards Wrapper (aka ObolLidoSplit) OBOL_LIDO_SPLIT_FACTORY = "0xA9d94139A310150Ca1163b5E23f3E1dbb7D9E2A6" OBOL_LIDO_SPLIT_IMPL = "0x2fB59065F049e0D0E3180C6312FA0FeB5Bbf0FE3" + +SANDBOX_REPO = "" diff --git a/interfaces/DepositSecurityModule.json b/interfaces/DepositSecurityModule.json index fce979394..c02c8811b 100644 --- a/interfaces/DepositSecurityModule.json +++ b/interfaces/DepositSecurityModule.json @@ -1 +1,461 @@ -[{"inputs":[{"internalType":"address","name":"_lido","type":"address"},{"internalType":"address","name":"_depositContract","type":"address"},{"internalType":"address","name":"_stakingRouter","type":"address"},{"internalType":"uint256","name":"_maxDepositsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_minDepositBlockDistance","type":"uint256"},{"internalType":"uint256","name":"_pauseIntentValidityPeriodBlocks","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DepositInactiveModule","type":"error"},{"inputs":[],"name":"DepositNoQuorum","type":"error"},{"inputs":[],"name":"DepositNonceChanged","type":"error"},{"inputs":[],"name":"DepositRootChanged","type":"error"},{"inputs":[],"name":"DepositTooFrequent","type":"error"},{"inputs":[],"name":"DepositUnexpectedBlockHash","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"DuplicateAddress","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotAGuardian","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotAnOwner","type":"error"},{"inputs":[],"name":"PauseIntentExpired","type":"error"},{"inputs":[],"name":"SignaturesNotSorted","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"inputs":[{"internalType":"string","name":"parameter","type":"string"}],"name":"ZeroParameter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"GuardianQuorumChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MaxDepositsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinDepositBlockDistanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"PauseIntentValidityPeriodBlocksChanged","type":"event"},{"inputs":[],"name":"ATTEST_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"contract ILido","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_ROUTER","outputs":[{"internalType":"contract IStakingRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardians","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"canDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"depositCalldata","type":"bytes"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature[]","name":"sortedGuardianSignatures","type":"tuple[]"}],"name":"depositBufferedEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getGuardianIndex","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardianQuorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardians","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinDepositBlockDistance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseIntentValidityPeriodBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature","name":"sig","type":"tuple"}],"name":"pauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"removeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setGuardianQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMaxDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMinDepositBlockDistance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setPauseIntentValidityPeriodBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"unpauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[ + { + "inputs": [ + { "internalType": "address", "name": "_lido", "type": "address" }, + { + "internalType": "address", + "name": "_depositContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_stakingRouter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_maxDepositsPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minDepositBlockDistance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_pauseIntentValidityPeriodBlocks", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "DepositInactiveModule", "type": "error" }, + { "inputs": [], "name": "DepositNoQuorum", "type": "error" }, + { "inputs": [], "name": "DepositNonceChanged", "type": "error" }, + { "inputs": [], "name": "DepositRootChanged", "type": "error" }, + { "inputs": [], "name": "DepositTooFrequent", "type": "error" }, + { "inputs": [], "name": "DepositUnexpectedBlockHash", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "DuplicateAddress", + "type": "error" + }, + { "inputs": [], "name": "InvalidSignature", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "NotAGuardian", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "NotAnOwner", + "type": "error" + }, + { "inputs": [], "name": "PauseIntentExpired", "type": "error" }, + { "inputs": [], "name": "SignaturesNotSorted", "type": "error" }, + { + "inputs": [{ "internalType": "string", "name": "field", "type": "string" }], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [ + { "internalType": "string", "name": "parameter", "type": "string" } + ], + "name": "ZeroParameter", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "guardian", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint24", + "name": "stakingModuleId", + "type": "uint24" + } + ], + "name": "DepositsPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "stakingModuleId", + "type": "uint24" + } + ], + "name": "DepositsUnpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "GuardianAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "GuardianQuorumChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "guardian", + "type": "address" + } + ], + "name": "GuardianRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "MaxDepositsChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "MinDepositBlockDistanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "PauseIntentValidityPeriodBlocksChanged", + "type": "event" + }, + { + "inputs": [], + "name": "ATTEST_MESSAGE_PREFIX", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEPOSIT_CONTRACT", + "outputs": [ + { + "internalType": "contract IDepositContract", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LIDO", + "outputs": [ + { "internalType": "contract ILido", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSE_MESSAGE_PREFIX", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_ROUTER", + "outputs": [ + { + "internalType": "contract IStakingRouter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "newQuorum", "type": "uint256" } + ], + "name": "addGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "addresses", "type": "address[]" }, + { "internalType": "uint256", "name": "newQuorum", "type": "uint256" } + ], + "name": "addGuardians", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + } + ], + "name": "canDeposit", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "blockNumber", "type": "uint256" }, + { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" }, + { "internalType": "bytes32", "name": "depositRoot", "type": "bytes32" }, + { + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "bytes", "name": "depositCalldata", "type": "bytes" }, + { + "components": [ + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "vs", "type": "bytes32" } + ], + "internalType": "struct DepositSecurityModule.Signature[]", + "name": "sortedGuardianSignatures", + "type": "tuple[]" + } + ], + "name": "depositBufferedEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "getGuardianIndex", + "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGuardianQuorum", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGuardians", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaxDeposits", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMinDepositBlockDistance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPauseIntentValidityPeriodBlocks", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "isGuardian", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "blockNumber", "type": "uint256" }, + { + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + }, + { + "components": [ + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "vs", "type": "bytes32" } + ], + "internalType": "struct DepositSecurityModule.Signature", + "name": "sig", + "type": "tuple" + } + ], + "name": "pauseDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "newQuorum", "type": "uint256" } + ], + "name": "removeGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "newValue", "type": "uint256" } + ], + "name": "setGuardianQuorum", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "newValue", "type": "uint256" } + ], + "name": "setMaxDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "newValue", "type": "uint256" } + ], + "name": "setMinDepositBlockDistance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newValue", "type": "address" } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "newValue", "type": "uint256" } + ], + "name": "setPauseIntentValidityPeriodBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "stakingModuleId", + "type": "uint256" + } + ], + "name": "unpauseDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/interfaces/Sandbox.json b/interfaces/Sandbox.json new file mode 100644 index 000000000..632231338 --- /dev/null +++ b/interfaces/Sandbox.json @@ -0,0 +1 @@ +[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_keysCount","type":"uint256"},{"name":"_publicKeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getType","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"clearNodeOperatorPenalty","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_offset","type":"uint256"},{"name":"_limit","type":"uint256"}],"name":"getNodeOperatorIds","outputs":[{"name":"nodeOperatorIds","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_offset","type":"uint256"},{"name":"_limit","type":"uint256"}],"name":"getSigningKeys","outputs":[{"name":"pubkeys","type":"bytes"},{"name":"signatures","type":"bytes"},{"name":"used","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fromIndex","type":"uint256"},{"name":"_keysCount","type":"uint256"}],"name":"removeSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorIsActive","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_name","type":"string"}],"name":"setNodeOperatorName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_totalRewardShares","type":"uint256"}],"name":"getRewardsDistribution","outputs":[{"name":"recipients","type":"address[]"},{"name":"shares","type":"uint256[]"},{"name":"penalized","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_indexFrom","type":"uint256"},{"name":"_indexTo","type":"uint256"}],"name":"invalidateReadyToDepositKeysRange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_locator","type":"address"},{"name":"_type","type":"bytes32"},{"name":"_stuckPenaltyDelay","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_delay","type":"uint256"}],"name":"setStuckPenaltyDelay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStuckPenaltyDelay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fromIndex","type":"uint256"},{"name":"_keysCount","type":"uint256"}],"name":"removeSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"isOperatorPenalized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"deactivateNodeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"STAKING_ROUTER_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_keysCount","type":"uint256"},{"name":"_publicKeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getActiveNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_rewardAddress","type":"address"}],"name":"addNodeOperator","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getContractVersion","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getUnusedSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"onRewardsMinted","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_NODE_OPERATOR_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"onWithdrawalCredentialsChanged","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"activateNodeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_rewardAddress","type":"address"}],"name":"setNodeOperatorRewardAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fullInfo","type":"bool"}],"name":"getNodeOperator","outputs":[{"name":"active","type":"bool"},{"name":"name","type":"string"},{"name":"rewardAddress","type":"address"},{"name":"totalVettedValidators","type":"uint64"},{"name":"totalExitedValidators","type":"uint64"},{"name":"totalAddedValidators","type":"uint64"},{"name":"totalDepositedValidators","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_locator","type":"address"},{"name":"_type","type":"bytes32"},{"name":"_stuckPenaltyDelay","type":"uint256"}],"name":"finalizeUpgrade_v2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStakingModuleSummary","outputs":[{"name":"totalExitedValidators","type":"uint256"},{"name":"totalDepositedValidators","type":"uint256"},{"name":"depositableValidatorsCount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorIds","type":"bytes"},{"name":"_exitedValidatorsCounts","type":"bytes"}],"name":"updateExitedValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorIds","type":"bytes"},{"name":"_stuckValidatorsCounts","type":"bytes"}],"name":"updateStuckValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_refundedValidatorsCount","type":"uint256"}],"name":"updateRefundedValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_isTargetLimitActive","type":"bool"},{"name":"_targetLimit","type":"uint256"}],"name":"updateTargetValidatorsLimits","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_vettedSigningKeysCount","type":"uint64"}],"name":"setNodeOperatorStakingLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorSummary","outputs":[{"name":"isTargetLimitActive","type":"bool"},{"name":"targetValidatorsCount","type":"uint256"},{"name":"stuckValidatorsCount","type":"uint256"},{"name":"refundedValidatorsCount","type":"uint256"},{"name":"stuckPenaltyEndTimestamp","type":"uint256"},{"name":"totalExitedValidators","type":"uint256"},{"name":"totalDepositedValidators","type":"uint256"},{"name":"depositableValidatorsCount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"getSigningKey","outputs":[{"name":"key","type":"bytes"},{"name":"depositSignature","type":"bytes"},{"name":"used","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NODE_OPERATOR_NAME_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_depositsCount","type":"uint256"},{"name":"","type":"bytes"}],"name":"obtainDepositData","outputs":[{"name":"publicKeys","type":"bytes"},{"name":"signatures","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getKeysOpIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNonce","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLocator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SET_NODE_OPERATOR_LIMIT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getTotalSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_STUCK_PENALTY_DELAY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"onExitedAndStuckValidatorsCountsUpdated","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NODE_OPERATORS_COUNT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKeyOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_exitedValidatorsCount","type":"uint256"},{"name":"_stuckValidatorsCount","type":"uint256"}],"name":"unsafeUpdateValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_SIGNING_KEYS","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"isOperatorPenaltyCleared","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"stakingLimit","type":"uint64"}],"name":"NodeOperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"NodeOperatorActiveSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"name","type":"string"}],"name":"NodeOperatorNameSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"rewardAddress","type":"address"}],"name":"NodeOperatorRewardAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"totalKeysTrimmed","type":"uint64"}],"name":"NodeOperatorTotalKeysTrimmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"keysOpIndex","type":"uint256"}],"name":"KeysOpIndexSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"moduleType","type":"bytes32"}],"name":"StakingModuleTypeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"sharesAmount","type":"uint256"}],"name":"RewardsDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"locatorAddress","type":"address"}],"name":"LocatorContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"approvedValidatorsCount","type":"uint256"}],"name":"VettedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"depositedValidatorsCount","type":"uint256"}],"name":"DepositedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"exitedValidatorsCount","type":"uint256"}],"name":"ExitedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"totalValidatorsCount","type":"uint256"}],"name":"TotalSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nonce","type":"uint256"}],"name":"NonceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"stuckPenaltyDelay","type":"uint256"}],"name":"StuckPenaltyDelayChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"stuckValidatorsCount","type":"uint256"},{"indexed":false,"name":"refundedValidatorsCount","type":"uint256"},{"indexed":false,"name":"stuckPenaltyEndTimestamp","type":"uint256"}],"name":"StuckPenaltyStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"targetValidatorsCount","type":"uint256"}],"name":"TargetValidatorsCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipientAddress","type":"address"},{"indexed":false,"name":"sharesPenalizedAmount","type":"uint256"}],"name":"NodeOperatorPenalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}] \ No newline at end of file diff --git a/interfaces/v3/DepositSecurityModuleV3.json b/interfaces/v3/DepositSecurityModuleV3.json deleted file mode 100644 index fce979394..000000000 --- a/interfaces/v3/DepositSecurityModuleV3.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_lido","type":"address"},{"internalType":"address","name":"_depositContract","type":"address"},{"internalType":"address","name":"_stakingRouter","type":"address"},{"internalType":"uint256","name":"_maxDepositsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_minDepositBlockDistance","type":"uint256"},{"internalType":"uint256","name":"_pauseIntentValidityPeriodBlocks","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DepositInactiveModule","type":"error"},{"inputs":[],"name":"DepositNoQuorum","type":"error"},{"inputs":[],"name":"DepositNonceChanged","type":"error"},{"inputs":[],"name":"DepositRootChanged","type":"error"},{"inputs":[],"name":"DepositTooFrequent","type":"error"},{"inputs":[],"name":"DepositUnexpectedBlockHash","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"DuplicateAddress","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotAGuardian","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotAnOwner","type":"error"},{"inputs":[],"name":"PauseIntentExpired","type":"error"},{"inputs":[],"name":"SignaturesNotSorted","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"inputs":[{"internalType":"string","name":"parameter","type":"string"}],"name":"ZeroParameter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"GuardianQuorumChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MaxDepositsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinDepositBlockDistanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"PauseIntentValidityPeriodBlocksChanged","type":"event"},{"inputs":[],"name":"ATTEST_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"contract ILido","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_ROUTER","outputs":[{"internalType":"contract IStakingRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardians","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"canDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"depositCalldata","type":"bytes"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature[]","name":"sortedGuardianSignatures","type":"tuple[]"}],"name":"depositBufferedEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getGuardianIndex","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardianQuorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardians","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinDepositBlockDistance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseIntentValidityPeriodBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature","name":"sig","type":"tuple"}],"name":"pauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"removeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setGuardianQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMaxDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMinDepositBlockDistance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setPauseIntentValidityPeriodBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"unpauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/scripts/helpers/check.sh b/scripts/helpers/check.sh new file mode 100755 index 000000000..f92f68b5b --- /dev/null +++ b/scripts/helpers/check.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Set RPC URL +RPC_URL="http://127.0.0.1:8555" + +# Locator address +LOCATOR_ADDRESS="0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" +echo "Locator Address:" +cast call --rpc-url $RPC_URL $LOCATOR_ADDRESS "proxy__getImplementation()" --trace + +# Staking router implementation +STAKING_ROUTER="0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" +echo "Staking Router Implementation:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "proxy__getImplementation()" --trace + +# Pause role +PAUSE_ROLE="0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" +ADDRESS1="0x045dd46212A178428c088573A7d102B9d89a022A" +echo "Pause Role:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $PAUSE_ROLE $ADDRESS1 --trace + +# Resume role +RESUME_ROLE="0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" +echo "Resume Role:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $RESUME_ROLE $ADDRESS1 --trace + +# Unvetting role +UNVETTING_ROLE="0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" +ADDRESS2="0x389D2352b39962cE98D990a979639C1E07ed500f" +echo "Unvetting Role:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $UNVETTING_ROLE $ADDRESS2 --trace + +# SR version + +echo "staking router version:" +cast call --rpc-url $RPC_URL $STAKING_ROUTER "getContractVersion()(uint256)" --trace + + +# nor implementation was changed + +NOR="0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" + +echo "nor implemertation was changed" +cast call --rpc-url $RPC_URL $NOR "implementation()" --trace + +# nor version +echo "not version" +cast call --rpc-url $RPC_URL $NOR "getContractVersion()(uint256)" --trace + +# ao impl +AO=0x4E97A3972ce8511D87F334dA17a2C332542a5246 +echo "ao implementation" +cast call --rpc-url $RPC_URL $AO "proxy__getImplementation()" --trace + +echo "ao version" +cast call --rpc-url $RPC_URL $AO "getContractVersion()(uint256)" --trace + + +# vebo has MANAGE_CONSENSUS_VERSION_ROLE role + +MANAGE_CONSENSUS_VERSION_ROLE="0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" +VALIDATORS_EXIT_BUS_ORACLE="0xffDDF7025410412deaa05E3E1cE68FE53208afcb" +AGENT="0xE92329EC7ddB11D25e25b3c21eeBf11f15eB325d" +echo "vebo has MANAGE_CONSENSUS_VERSION_ROLE role:" +cast call --rpc-url $RPC_URL $VALIDATORS_EXIT_BUS_ORACLE "hasRole(bytes32,address)(bool)" $MANAGE_CONSENSUS_VERSION_ROLE $AGENT --trace + + +echo "VEBO getConsensusVersion" +cast call --rpc-url $RPC_URL $VALIDATORS_EXIT_BUS_ORACLE "getConsensusVersion()(uint256)" --trace + diff --git a/scripts/helpers/check_holesky.py b/scripts/helpers/check_holesky.py new file mode 100644 index 000000000..1175c9fd0 --- /dev/null +++ b/scripts/helpers/check_holesky.py @@ -0,0 +1,77 @@ +from brownie import network, Contract, accounts, rpc, chain + + +def main(): + # ABI of the contract (replace with actual ABI of your contract) + abi = [ + { + "inputs": [], + "name": "proxy__getImplementation", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "implementation", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + ] + + contract_address = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" + + contract = Contract.from_abi("LidoLocator", contract_address, abi) + + address = contract.proxy__getImplementation() + + # Print the transaction details + print(f"Locator impl: {address}") + + # Staking router implementation + STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" + + srAbi = [ + { + "inputs": [ + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, + ], + "name": "hasRole", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", + } + ] + # Pause role + PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" + ADDRESS1 = "0x045dd46212A178428c088573A7d102B9d89a022A" + + sr = Contract.from_abi("StakingRouter", STAKING_ROUTER, srAbi) + res = sr.hasRole(PAUSE_ROLE, ADDRESS1) + + print(f"old dsm pause role: {res}") + + UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" + ADDRESS2 = "0xe0aA552A10d7EC8760Fc6c246D391E698a82dDf9" + + res2 = sr.hasRole(UNVETTING_ROLE, ADDRESS2) + + print(f"new dsm unvetting role: {res2}") + + sdvt_proxy = "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6" + sdvt = Contract.from_abi("SimpleDVT", sdvt_proxy, abi) + + sdvt_impl = sdvt.implementation() + + # Print the transaction details + print(f"Sdvt impl: {sdvt_impl}") + + sandbox_proxy_addr = "0xD6C2ce3BB8bea2832496Ac8b5144819719f343AC" + sandbox_proxy = Contract.from_abi("Sandbox", sandbox_proxy_addr, abi) + + sandbox_proxy_impl = sandbox_proxy.implementation() + + # Print the transaction details + print(f"Sandbox impl: {sandbox_proxy_impl }") diff --git a/scripts/helpers/check_mainnet.py b/scripts/helpers/check_mainnet.py new file mode 100644 index 000000000..15a6c640c --- /dev/null +++ b/scripts/helpers/check_mainnet.py @@ -0,0 +1,69 @@ +from brownie import network, Contract, accounts, rpc, chain + + +def main(): + # ABI of the contract (replace with actual ABI of your contract) + abi = [ + { + "inputs": [], + "name": "proxy__getImplementation", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "implementation", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + ] + + contract_address = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" + + contract = Contract.from_abi("LidoLocator", contract_address, abi) + + address = contract.proxy__getImplementation() + + # Print the transaction details + print(f"Locator impl: {address}") + + # Staking router implementation + STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" + + srAbi = [ + { + "inputs": [ + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, + ], + "name": "hasRole", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", + } + ] + # Pause role + PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" + ADDRESS1 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" + + sr = Contract.from_abi("StakingRouter", STAKING_ROUTER, srAbi) + res = sr.hasRole(PAUSE_ROLE, ADDRESS1) + + print(f"old dsm pause role: {res}") + + UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" + ADDRESS2 = "0xf9C8Cf55f2E520B08d869df7bc76aa3d3ddDF913" + + res2 = sr.hasRole(UNVETTING_ROLE, ADDRESS2) + + print(f"new dsm unvetting role: {res2}") + + sdvt_proxy = "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" + sdvt = Contract.from_abi("SimpleDVT", sdvt_proxy, abi) + + sdvt_impl = sdvt.implementation() + + # Print the transaction details + print(f"Sdvt impl: {sdvt_impl}") diff --git a/scripts/helpers/exec_voting.py b/scripts/helpers/exec_voting.py new file mode 100644 index 000000000..f0dc2d326 --- /dev/null +++ b/scripts/helpers/exec_voting.py @@ -0,0 +1,68 @@ +from brownie import network, Contract, accounts, rpc, chain + + +def main(): + # ABI of the contract (replace with actual ABI of your contract) + abi = [ + { + "constant": False, + "inputs": [ + {"name": "_voteId", "type": "uint256"}, + {"name": "_supports", "type": "bool"}, + {"name": "_executesIfDecided_deprecated", "type": "bool"}, + ], + "name": "vote", + "outputs": [], + "payable": False, + "stateMutability": "nonpayable", + "type": "function", + }, + { + "constant": False, + "inputs": [{"name": "_voteId", "type": "uint256"}], + "name": "executeVote", + "outputs": [], + "payable": False, + "stateMutability": "nonpayable", + "type": "function", + }, + ] + # mainnet + # account1 = accounts.at("0xb8d83908aab38a159f3da47a59d84db8e1838712", force=True) + # account2 = accounts.at("0xa2dfc431297aee387c05beef507e5335e684fbcd", force=True) + # vote_executor = "0x3e40d73eb977dc6a537af587d48316fee66e9c8c" + + # сontract_address = "0x2e59A20f205bB85a89C53f1936454680651E618e" + + # holesky + account1 = accounts.at("0xBA59A84C6440E8cccfdb5448877E26F1A431Fc8B", force=True) + account2 = accounts.at("0x1D835790d93a28fb30d998C0CB27426E5D2D7C8c", force=True) + vote_executor = "0xaa6bfBCD634EE744CB8FE522b29ADD23124593D3" + + сontract_address = "0xdA7d2573Df555002503F29aA4003e398d28cc00f" + + contract = Contract.from_abi("Vote", сontract_address, abi) + + vote_id = 84 # Replace with the actual vote ID + supports = True # Set to True or False based on your requirement + executes_if_decided = False # Set to True or False based on your requirement + + contract.vote(vote_id, supports, executes_if_decided, {"from": account1}) + contract.vote(vote_id, supports, executes_if_decided, {"from": account2}) + + days = 3 + hours = 5 + total_sleep_time = (days * 24 * 60 * 60) + (hours * 60 * 60) # 3 days and 2 hours in seconds + + chain.sleep(total_sleep_time) + # Mine a block + chain.mine() + + tx = contract.executeVote(vote_id, {"from": vote_executor}) + + # Print the transaction details + print(f"Transaction hash: {tx.txid}") + print(f"Gas used: {tx.gas_used}") + + # Disconnect from the network + network.disconnect() diff --git a/scripts/helpers/impersonate.py b/scripts/helpers/impersonate.py new file mode 100644 index 000000000..95fafe937 --- /dev/null +++ b/scripts/helpers/impersonate.py @@ -0,0 +1,10 @@ +from brownie import accounts + + +def main(): + # Address to impersonate + holder = "0xa2dfc431297aee387c05beef507e5335e684fbcd" + holder2 = "0xb8d83908aab38a159f3da47a59d84db8e1838712" + + accounts.at(holder, force=True) + accounts.at(holder2, force=True) diff --git a/scripts/vote_sr_v2_holesky.py b/scripts/vote_sr_v2_holesky.py index 8eba6658e..ab3b06283 100644 --- a/scripts/vote_sr_v2_holesky.py +++ b/scripts/vote_sr_v2_holesky.py @@ -9,10 +9,17 @@ 7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo 8. Update `NodeOperatorsRegistry` implementation 9. Finalize NOR upgrade -10. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, -11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, -12. Grant manage consensus role to agent ${AGENT}` -13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo +11. Update `SimpleDVT` implementation +12. Finalize SimpleDVT upgrade +13. Publish new `Sandbox` implementation in Sandbox app APM repo +14. Update `Sandbox` implementation +15. Finalize Sandbox upgrade +13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, +14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +15. Grant manage consensus role to agent ${AGENT}` +16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +17. Revoke manage consensus role from agent ${AGENT}" """ import time @@ -31,13 +38,16 @@ contracts, LIDO_LOCATOR_IMPL, STAKING_ROUTER_IMPL, - NOR_IMPL, ACCOUNTING_ORACLE_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, AGENT, ) -from utils.permissions import encode_permission_revoke, encode_permission_grant -from utils.repo import add_implementation_to_nor_app_repo +from utils.repo import ( + add_implementation_to_nor_app_repo, + add_implementation_to_sdvt_app_repo, + add_implementation_to_sandbox_app_repo, +) from utils.kernel import update_app_implementation @@ -50,9 +60,12 @@ PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] -NOR_CONTENT_URI = "0x" + "00" * 51 # ? NOR_VERSION = ["2", "0", "0"] +SDVT_VERSION = ["2", "0", "0"] +SANDBOX_VERSION = ["2", "0", "0"] NOR_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" +SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" +SANDBOX_APP_ID = "0x85d2fceef13a6c14c43527594f79fb91a8ef8f15024a43486efac8df2b11e632" AO_CONSENSUS_VERSION = 2 VEBO_CONSENSUS_VERSION = 2 @@ -79,6 +92,16 @@ def encode_nor_finalize() -> Tuple[str, str]: return proxy.address, proxy.finalizeUpgrade_v3.encode_input() +def encode_sdvt_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.simple_dvt) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_sandbox_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.sandbox) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: proxy = interface.OssifiableProxy(contracts.accounting_oracle) return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) @@ -94,9 +117,27 @@ def encode_set_consensus_version() -> Tuple[str, str]: return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) +def get_repo_uri(repo_address: str) -> str: + contract = interface.Repo(repo_address).getLatest() + return contract["contentURI"] + + +def get_repo_version(repo_address: str) -> tuple[int, int, int]: + contract = interface.Repo(repo_address).getLatest() + return contract["semanticVersion"] + + def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: """Prepare and run voting.""" + nor_repo = contracts.nor_app_repo.address + simple_dvt_repo = contracts.simple_dvt_app_repo.address + sandbox_repo = contracts.sandbox_repo.address + + nor_uri = get_repo_uri(nor_repo) + simple_dvt_uri = get_repo_uri(simple_dvt_repo) + sandbox_uri = get_repo_uri(sandbox_repo) + call_script_items = [ # 1) agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), @@ -108,7 +149,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T contracts.staking_router.revokeRole.encode_input( # keccak256 STAKING_MODULE_PAUSE_ROLE "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", - contracts.deposit_security_module, + contracts.deposit_security_module_v2, ), ) ] @@ -121,7 +162,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T contracts.staking_router.revokeRole.encode_input( # keccak256 STAKING_MODULE_RESUME_ROLE "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", - contracts.deposit_security_module, + contracts.deposit_security_module_v2, ), ) ] @@ -134,7 +175,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T contracts.staking_router.grantRole.encode_input( # keccak256 STAKING_MODULE_UNVETTING_ROLE "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", - contracts.deposit_security_module_v3, + contracts.deposit_security_module, ), ) ] @@ -144,16 +185,28 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # 6) encode_staking_router_finalize(), # 7) - add_implementation_to_nor_app_repo(NOR_VERSION, NOR_IMPL, NOR_CONTENT_URI), + add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), # 8) - update_app_implementation(NOR_APP_ID, NOR_IMPL), + update_app_implementation(NOR_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), # 9) encode_nor_finalize(), # 10) - agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), # 11) - encode_ao_finalize(), + update_app_implementation(SDVT_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), # 12) + encode_sdvt_finalize(), + # 13) + add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), + # 14) + update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # 15) + encode_sandbox_finalize(), + # 16) + agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + # 17) + encode_ao_finalize(), + # 18) agent_forward( [ ( @@ -166,8 +219,21 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ) ] ), - # 13) + # 19) agent_forward([encode_set_consensus_version()]), + # 20) + agent_forward( + [ + ( + contracts.validators_exit_bus_oracle.address, + contracts.validators_exit_bus_oracle.revokeRole.encode_input( + # keccak256 MANAGE_CONSENSUS_VERSION_ROLE + "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", + AGENT, + ), + ) + ] + ), ] vote_desc_items = [ @@ -180,10 +246,17 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", "8. Update `NodeOperatorsRegistry` implementation", "9. Finalize NOR upgrade", - "10. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", - "11. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - "12. Grant manage consensus role to agent ${AGENT}", - "13. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", + "11. Update `SimpleDVT` implementation", + "12. Finalize SimpleDVT upgrade", + "13. Publish new `Sandbox` implementation in Sandbox app APM repo", + "14. Update `Sandbox` implementation", + "15. Finalize Sandbox upgrade", + "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + "18. Grant manage consensus role to agent ${AGENT}", + "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + "20. Revoke manage consensus role from agent ${AGENT}", ] vote_items = bake_vote_items(vote_desc_items, call_script_items) diff --git a/scripts/vote_sr_v2_mainnet.py b/scripts/vote_sr_v2_mainnet.py new file mode 100644 index 000000000..5101c85f5 --- /dev/null +++ b/scripts/vote_sr_v2_mainnet.py @@ -0,0 +1,255 @@ +""" +SR V2 +1. Update locator implementation +2. Revoke pause role from old DSM +3. Revoke resume role from old DSM +4. Grant unvetting role to new DSM +5. Update SR implementation +6. Call finalize upgrade on SR +7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo +8. Update `NodeOperatorsRegistry` implementation +9. Finalize NOR upgrade +10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo +11. Update `SimpleDVT` implementation +12. Finalize SimpleDVT upgrade +13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, +14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +15. Grant manage consensus role to agent ${AGENT}` +16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +17. Revoke manage consensus role from agent ${AGENT} +""" + +import time + +try: + from brownie import interface, accounts +except ImportError: + print("You're probably running inside Brownie console. Please call:") + print("set_console_globals(interface=interface)") + + +from typing import Dict, Tuple, Optional +from utils.config import ( + get_deployer_account, + get_is_live, + contracts, + LIDO_LOCATOR_IMPL, + STAKING_ROUTER_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, + ACCOUNTING_ORACLE_IMPL, + AGENT, +) + +from utils.repo import add_implementation_to_nor_app_repo, add_implementation_to_sdvt_app_repo + +from utils.kernel import update_app_implementation + +from utils.voting import bake_vote_items, confirm_vote_script, create_vote + +from brownie.network.transaction import TransactionReceipt +from utils.agent import agent_forward + + +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000] +MAX_DEPOSITS_PER_BLOCK = [50, 50] +MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25] +NOR_VERSION = ["5", "0", "0"] +SDVT_VERSION = ["2", "0", "0"] +NOR_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" +SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 + + +def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.lido_locator) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_staking_router_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.staking_router) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_staking_router_finalize() -> Tuple[str, str]: + proxy = interface.StakingRouter(contracts.staking_router) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input( + PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES + ) + + +def encode_nor_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.node_operators_registry) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_sdvt_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.simple_dvt) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.accounting_oracle) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_ao_finalize() -> Tuple[str, str]: + proxy = interface.AccountingOracle(contracts.accounting_oracle) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) + + +def encode_set_consensus_version() -> Tuple[str, str]: + proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) + return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) + + +def get_repo_uri(repo_address: str) -> str: + contract = interface.Repo(repo_address).getLatest() + return contract["contentURI"] + + +def get_repo_version(repo_address: str) -> tuple[int, int, int]: + contract = interface.Repo(repo_address).getLatest() + return contract["semanticVersion"] + + +def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: + """Prepare and run voting.""" + + nor_repo = contracts.nor_app_repo.address + simple_dvt_repo = contracts.simple_dvt_app_repo.address + + nor_uri = get_repo_uri(nor_repo) + simple_dvt_uri = get_repo_uri(simple_dvt_repo) + + call_script_items = [ + # 1) + agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), + # 2) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.revokeRole.encode_input( + # keccak256 STAKING_MODULE_PAUSE_ROLE + "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", + contracts.deposit_security_module_v2, + ), + ) + ] + ), + # 3) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.revokeRole.encode_input( + # keccak256 STAKING_MODULE_RESUME_ROLE + "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", + contracts.deposit_security_module_v2, + ), + ) + ] + ), + # 4) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.grantRole.encode_input( + # keccak256 STAKING_MODULE_UNVETTING_ROLE + "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", + contracts.deposit_security_module, + ), + ) + ] + ), + # 5) + agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), + # 6) + encode_staking_router_finalize(), + # 7) + add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), + # 8) + update_app_implementation(NOR_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # 9) + encode_nor_finalize(), + # 10) + add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), + # 11) + update_app_implementation(SDVT_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # 12) + encode_sdvt_finalize(), + # 13) + agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + # 14) + encode_ao_finalize(), + # 15) + agent_forward( + [ + ( + contracts.validators_exit_bus_oracle.address, + contracts.validators_exit_bus_oracle.grantRole.encode_input( + # keccak256 MANAGE_CONSENSUS_VERSION_ROLE + "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", + AGENT, + ), + ) + ] + ), + # 16) + agent_forward([encode_set_consensus_version()]), + # 17) + agent_forward( + [ + ( + contracts.validators_exit_bus_oracle.address, + contracts.validators_exit_bus_oracle.revokeRole.encode_input( + # keccak256 MANAGE_CONSENSUS_VERSION_ROLE + "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", + AGENT, + ), + ) + ] + ), + ] + + vote_desc_items = [ + "1. Update locator implementation", + "2. Revoke pause role from old DSM", + "3. Revoke resume role from old DSM", + "4. Grant unvetting role to new DSM", + "5. Update SR implementation", + "6. Call finalize upgrade on SR", + "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + "8. Update `NodeOperatorsRegistry` implementation", + "9. Finalize NOR upgrade", + "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", + "11. Update `SimpleDVT` implementation", + "12. Finalize SimpleDVT upgrade", + "13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + "14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + "15. Grant manage consensus role to agent ${AGENT}", + "16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + "17. Revoke manage consensus role from agent ${AGENT}", + ] + + vote_items = bake_vote_items(vote_desc_items, call_script_items) + + return confirm_vote_script(vote_items, silent) and list(create_vote(vote_items, tx_params)) + + +def main(): + tx_params = {"from": get_deployer_account()} + + if get_is_live(): + tx_params["max_fee"] = "300 gwei" + tx_params["priority_fee"] = "2 gwei" + + print(f"tx = {tx_params}") + + vote_id, _ = start_vote(tx_params=tx_params, silent=False) + + vote_id >= 0 and print(f"Vote created: {vote_id}.") + + time.sleep(5) # hack for waiting thread #2. diff --git a/utils/config.py b/utils/config.py index 00dd17bb3..3a4261701 100644 --- a/utils/config.py +++ b/utils/config.py @@ -173,6 +173,10 @@ def node_operators_registry(self) -> interface.NodeOperatorsRegistry: def simple_dvt(self) -> interface.SimpleDVT: return interface.SimpleDVT(SIMPLE_DVT) + @property + def sandbox(self) -> interface.SimpleDVT: + return interface.Sandbox(SANDBOX) + @property def legacy_oracle(self) -> interface.LegacyOracle: return interface.LegacyOracle(LEGACY_ORACLE) @@ -182,8 +186,8 @@ def deposit_security_module_v1(self) -> interface.DepositSecurityModule: return interface.DepositSecurityModuleV1(DEPOSIT_SECURITY_MODULE_V1) @property - def deposit_security_module_v3(self) -> interface.DepositSecurityModule: - return interface.DepositSecurityModuleV3(DEPOSIT_SECURITY_MODULE_V3) + def deposit_security_module_v2(self) -> interface.DepositSecurityModule: + return interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE_V2) @property def deposit_security_module(self) -> interface.DepositSecurityModule: @@ -253,6 +257,14 @@ def lido_app_repo(self) -> interface.Repo: def nor_app_repo(self) -> interface.Repo: return interface.Repo(NODE_OPERATORS_REGISTRY_REPO) + @property + def simple_dvt_app_repo(self) -> interface.Repo: + return interface.Repo(SIMPLE_DVT_REPO) + + @property + def sandbox_repo(self) -> interface.Repo: + return interface.Repo(SANDBOX_REPO) + @property def voting_app_repo(self) -> interface.Repo: return interface.Repo(VOTING_REPO) diff --git a/utils/repo.py b/utils/repo.py index 2ffd0d060..c44f6ec16 100644 --- a/utils/repo.py +++ b/utils/repo.py @@ -13,6 +13,14 @@ def add_implementation_to_nor_app_repo(version, address, content_uri): return _add_implementation_to_repo(contracts.nor_app_repo, version, address, content_uri) +def add_implementation_to_sdvt_app_repo(version, address, content_uri): + return _add_implementation_to_repo(contracts.simple_dvt_app_repo, version, address, content_uri) + + +def add_implementation_to_sandbox_app_repo(version, address, content_uri): + return _add_implementation_to_repo(contracts.sandbox_repo, version, address, content_uri) + + def add_implementation_to_voting_app_repo(version, address, content_uri): return _add_implementation_to_repo(contracts.voting_app_repo, version, address, content_uri) From 1c0195df85c8acfc0974a55ee185e8d5490091ca Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 20 Jun 2024 04:05:45 +0400 Subject: [PATCH 008/220] fix: mv check.sh --- scripts/check.sh | 70 ------------------------------------------------ 1 file changed, 70 deletions(-) delete mode 100755 scripts/check.sh diff --git a/scripts/check.sh b/scripts/check.sh deleted file mode 100755 index f92f68b5b..000000000 --- a/scripts/check.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -# Set RPC URL -RPC_URL="http://127.0.0.1:8555" - -# Locator address -LOCATOR_ADDRESS="0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -echo "Locator Address:" -cast call --rpc-url $RPC_URL $LOCATOR_ADDRESS "proxy__getImplementation()" --trace - -# Staking router implementation -STAKING_ROUTER="0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" -echo "Staking Router Implementation:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "proxy__getImplementation()" --trace - -# Pause role -PAUSE_ROLE="0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" -ADDRESS1="0x045dd46212A178428c088573A7d102B9d89a022A" -echo "Pause Role:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $PAUSE_ROLE $ADDRESS1 --trace - -# Resume role -RESUME_ROLE="0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" -echo "Resume Role:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $RESUME_ROLE $ADDRESS1 --trace - -# Unvetting role -UNVETTING_ROLE="0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" -ADDRESS2="0x389D2352b39962cE98D990a979639C1E07ed500f" -echo "Unvetting Role:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $UNVETTING_ROLE $ADDRESS2 --trace - -# SR version - -echo "staking router version:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "getContractVersion()(uint256)" --trace - - -# nor implementation was changed - -NOR="0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" - -echo "nor implemertation was changed" -cast call --rpc-url $RPC_URL $NOR "implementation()" --trace - -# nor version -echo "not version" -cast call --rpc-url $RPC_URL $NOR "getContractVersion()(uint256)" --trace - -# ao impl -AO=0x4E97A3972ce8511D87F334dA17a2C332542a5246 -echo "ao implementation" -cast call --rpc-url $RPC_URL $AO "proxy__getImplementation()" --trace - -echo "ao version" -cast call --rpc-url $RPC_URL $AO "getContractVersion()(uint256)" --trace - - -# vebo has MANAGE_CONSENSUS_VERSION_ROLE role - -MANAGE_CONSENSUS_VERSION_ROLE="0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" -VALIDATORS_EXIT_BUS_ORACLE="0xffDDF7025410412deaa05E3E1cE68FE53208afcb" -AGENT="0xE92329EC7ddB11D25e25b3c21eeBf11f15eB325d" -echo "vebo has MANAGE_CONSENSUS_VERSION_ROLE role:" -cast call --rpc-url $RPC_URL $VALIDATORS_EXIT_BUS_ORACLE "hasRole(bytes32,address)(bool)" $MANAGE_CONSENSUS_VERSION_ROLE $AGENT --trace - - -echo "VEBO getConsensusVersion" -cast call --rpc-url $RPC_URL $VALIDATORS_EXIT_BUS_ORACLE "getConsensusVersion()(uint256)" --trace - From 3f1d5d953b097ecc5b7f458191c77bbc5c3680ff Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 20 Jun 2024 10:49:47 +0400 Subject: [PATCH 009/220] fix: returned config values for aminnet --- configs/config_mainnet.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 6ceedfb28..79c5b3606 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -98,7 +98,7 @@ # LidoLocator LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x832698Daec363C9A7aB036C224Af5B21280b3AC6" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" # set address here after SR V2 deploy # Other upgrade addresses LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" @@ -169,7 +169,7 @@ FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT = 1350 # 6 days # OracleReportSanityChecker -ORACLE_REPORT_SANITY_CHECKER = "0x2e13f7644014F6E934E314F0371585845de7B986" +ORACLE_REPORT_SANITY_CHECKER = "0x9305c1Dbfe22c12c66339184C0025d7006f0f1cC" CHURN_VALIDATORS_PER_DAY_LIMIT = 20000 ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT = 500 # 5% ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% @@ -186,7 +186,7 @@ TOTAL_COVER_SHARES_BURNT = 0 # DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0xf9C8Cf55f2E520B08d869df7bc76aa3d3ddDF913" # dsm address after SR V2 enact +DEPOSIT_SECURITY_MODULE = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address after SR V2 enact DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact DSM_MAX_DEPOSITS_PER_BLOCK = 150 DSM_MIN_DEPOSIT_BLOCK_DISTANCE = 25 @@ -205,7 +205,7 @@ # AccountingOracle # and its corresponding HashConsensus ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0x654f70d8442EA18904FA1AD79114f7250F7E9336" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" # set address here after SR V2 deploy HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 From 45b06850d10d50d2450608324aedb81c415c47a3 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 20 Jun 2024 10:51:28 +0400 Subject: [PATCH 010/220] fix: doc --- scripts/vote_sr_v2_holesky.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/vote_sr_v2_holesky.py b/scripts/vote_sr_v2_holesky.py index ab3b06283..abe3f4bfa 100644 --- a/scripts/vote_sr_v2_holesky.py +++ b/scripts/vote_sr_v2_holesky.py @@ -15,11 +15,11 @@ 13. Publish new `Sandbox` implementation in Sandbox app APM repo 14. Update `Sandbox` implementation 15. Finalize Sandbox upgrade -13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, -14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, -15. Grant manage consensus role to agent ${AGENT}` -16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` -17. Revoke manage consensus role from agent ${AGENT}" +16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, +17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +18. Grant manage consensus role to agent ${AGENT}` +19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +20. Revoke manage consensus role from agent ${AGENT}" """ import time From d085b5f40afc7434785e0afef0f6130035658e0b Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 21 Jun 2024 12:36:10 +0400 Subject: [PATCH 011/220] fix: made template for voting sr v2 --- configs/config_holesky.py | 11 +-- configs/config_mainnet.py | 12 +-- scripts/helpers/exec_voting.py | 18 ++--- scripts/helpers/impersonate.py | 2 + .../{vote_sr_v2_holesky.py => vote_sr_v2.py} | 6 +- ...r_v2_mainnet.py => vote_sr_v2.py.template} | 77 ++++++++++++------- 6 files changed, 77 insertions(+), 49 deletions(-) rename scripts/{vote_sr_v2_holesky.py => vote_sr_v2.py} (97%) rename scripts/{vote_sr_v2_mainnet.py => vote_sr_v2.py.template} (81%) diff --git a/configs/config_holesky.py b/configs/config_holesky.py index 3f226b4bf..c04708fed 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -24,7 +24,7 @@ LEGACY_ORACLE = "0x072f72BE3AcFE2c52715829F2CD9061A6C8fF019" NODE_OPERATORS_REGISTRY = "0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" # set address here after deploy -NODE_OPERATORS_REGISTRY_IMPL = "0x6951b5Bd815043E3F842c1b026b0Fa888Cc2DD85" +NODE_OPERATORS_REGISTRY_IMPL = "0x6951b5Bd815043E3F842c1b026b0Fa888Cc2DD85" # set address here after SR V2 deploy # Aragon APM Repos VOTING_REPO = "0x2997EA0D07D79038D83Cb04b3BB9A2Bc512E3fDA" @@ -78,13 +78,13 @@ LIDO_LOCATOR = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -LIDO_LOCATOR_IMPL = "0xcCB53c9429d32594F404d01fbe9E65ED1DCda8D9" # set address here after deploy +LIDO_LOCATOR_IMPL = "0xcCB53c9429d32594F404d01fbe9E65ED1DCda8D9" # set address here after SR V2 deploy WITHDRAWAL_QUEUE = "0xc7cc160b58F8Bb0baC94b80847E2CF2800565C50" ORACLE_DAEMON_CONFIG = "0xC01fC1F2787687Bc656EAc0356ba9Db6e6b7afb7" -ORACLE_REPORT_SANITY_CHECKER = "0x7A4D8dF25f2A43505940232aC1397235899Fa8C" # should be changed for new +ORACLE_REPORT_SANITY_CHECKER = "0x7A4D8dF25f2A43505940232aC1397235899Fa8C" # set address here after SR V2 deploy BURNER = "0x4E46BD7147ccf666E1d73A3A456fC7a68de82eCA" -DEPOSIT_SECURITY_MODULE = "0xe0aA552A10d7EC8760Fc6c246D391E698a82dDf9" # dsm address after SR V2 +DEPOSIT_SECURITY_MODULE = "0xe0aA552A10d7EC8760Fc6c246D391E698a82dDf9" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0x045dd46212A178428c088573A7d102B9d89a022A" # dsm address before SR V2 enact ACCOUNTING_ORACLE = "0x4E97A3972ce8511D87F334dA17a2C332542a5246" ACCOUNTING_ORACLE_IMPL = "0x6b4BDe1086912A6Cb24ce3dB43b3466e6c72AFd3" # set address here after SR V2 deploy @@ -104,10 +104,11 @@ NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" +SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" +SANDBOX_APP_ID = "0x85d2fceef13a6c14c43527594f79fb91a8ef8f15024a43486efac8df2b11e632" SIMPLE_DVT = "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6" SIMPLE_DVT_REPO = "0x889dB59baf032E1dfD4fCA720e0833c24f1404C6" - SANDBOX = "0xD6C2ce3BB8bea2832496Ac8b5144819719f343AC" SANDBOX_REPO = "0x00E75B5527a876B3F10C23436a0b896C626812d0" diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 79c5b3606..984d59d96 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -98,7 +98,7 @@ # LidoLocator LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0x832698Daec363C9A7aB036C224Af5B21280b3AC6" # set address here after SR V2 deploy # Other upgrade addresses LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" @@ -123,7 +123,7 @@ ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" # NodeOperatorsRegistry aka Curated Staking Module -NODE_OPERATORS_REGISTRY_IMPL = "0x4D1B781ce59B8C184F63B99D39d6719A522f46B5" # set address after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x4D1B781ce59B8C184F63B99D39d6719A522f46B5" # set address here after SR V2 deploy ## see NodeOperatorsRegistry's proxy appId() NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY = 432000 @@ -186,7 +186,7 @@ TOTAL_COVER_SHARES_BURNT = 0 # DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address after SR V2 enact +DEPOSIT_SECURITY_MODULE = "0xf9C8Cf55f2E520B08d869df7bc76aa3d3ddDF913" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact DSM_MAX_DEPOSITS_PER_BLOCK = 150 DSM_MIN_DEPOSIT_BLOCK_DISTANCE = 25 @@ -205,7 +205,7 @@ # AccountingOracle # and its corresponding HashConsensus ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0x654f70d8442EA18904FA1AD79114f7250F7E9336" # set address here after SR V2 deploy HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 @@ -252,7 +252,7 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" -STAKING_ROUTER_IMPL = "0xD22363efee93190f82b52FCD62B7Dbcb920eF658" # set address here after deploy +STAKING_ROUTER_IMPL = "0xD22363efee93190f82b52FCD62B7Dbcb920eF658" # set address here after SR V2 deploy # Not a precise but still some estimation of the fees. Assume here that both modules are filled # SR_MODULES_FEE = curated_module_fee * (100% - sdvt_module_share) + sdvt_module_fee * sdvt_module_share @@ -303,4 +303,4 @@ OBOL_LIDO_SPLIT_FACTORY = "0xA9d94139A310150Ca1163b5E23f3E1dbb7D9E2A6" OBOL_LIDO_SPLIT_IMPL = "0x2fB59065F049e0D0E3180C6312FA0FeB5Bbf0FE3" -SANDBOX_REPO = "" +SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" diff --git a/scripts/helpers/exec_voting.py b/scripts/helpers/exec_voting.py index f0dc2d326..67b03f51c 100644 --- a/scripts/helpers/exec_voting.py +++ b/scripts/helpers/exec_voting.py @@ -28,22 +28,22 @@ def main(): }, ] # mainnet - # account1 = accounts.at("0xb8d83908aab38a159f3da47a59d84db8e1838712", force=True) - # account2 = accounts.at("0xa2dfc431297aee387c05beef507e5335e684fbcd", force=True) - # vote_executor = "0x3e40d73eb977dc6a537af587d48316fee66e9c8c" + account1 = accounts.at("0xb8d83908aab38a159f3da47a59d84db8e1838712", force=True) + account2 = accounts.at("0xa2dfc431297aee387c05beef507e5335e684fbcd", force=True) + vote_executor = "0x3e40d73eb977dc6a537af587d48316fee66e9c8c" - # сontract_address = "0x2e59A20f205bB85a89C53f1936454680651E618e" + сontract_address = "0x2e59A20f205bB85a89C53f1936454680651E618e" # holesky - account1 = accounts.at("0xBA59A84C6440E8cccfdb5448877E26F1A431Fc8B", force=True) - account2 = accounts.at("0x1D835790d93a28fb30d998C0CB27426E5D2D7C8c", force=True) - vote_executor = "0xaa6bfBCD634EE744CB8FE522b29ADD23124593D3" + # account1 = accounts.at("0xBA59A84C6440E8cccfdb5448877E26F1A431Fc8B", force=True) + # account2 = accounts.at("0x1D835790d93a28fb30d998C0CB27426E5D2D7C8c", force=True) + # vote_executor = "0xaa6bfBCD634EE744CB8FE522b29ADD23124593D3" - сontract_address = "0xdA7d2573Df555002503F29aA4003e398d28cc00f" + # сontract_address = "0xdA7d2573Df555002503F29aA4003e398d28cc00f" contract = Contract.from_abi("Vote", сontract_address, abi) - vote_id = 84 # Replace with the actual vote ID + vote_id = 175 # Replace with the actual vote ID supports = True # Set to True or False based on your requirement executes_if_decided = False # Set to True or False based on your requirement diff --git a/scripts/helpers/impersonate.py b/scripts/helpers/impersonate.py index 95fafe937..b5a3a72a9 100644 --- a/scripts/helpers/impersonate.py +++ b/scripts/helpers/impersonate.py @@ -2,6 +2,8 @@ def main(): + print(f"{accounts[0]}") + accounts.at(accounts[0], force=True) # Address to impersonate holder = "0xa2dfc431297aee387c05beef507e5335e684fbcd" holder2 = "0xb8d83908aab38a159f3da47a59d84db8e1838712" diff --git a/scripts/vote_sr_v2_holesky.py b/scripts/vote_sr_v2.py similarity index 97% rename from scripts/vote_sr_v2_holesky.py rename to scripts/vote_sr_v2.py index abe3f4bfa..695f38ff7 100644 --- a/scripts/vote_sr_v2_holesky.py +++ b/scripts/vote_sr_v2.py @@ -36,6 +36,9 @@ get_deployer_account, get_is_live, contracts, + NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + SDVT_APP_ID, + SANDBOX_APP_ID, LIDO_LOCATOR_IMPL, STAKING_ROUTER_IMPL, ACCOUNTING_ORACLE_IMPL, @@ -63,9 +66,6 @@ NOR_VERSION = ["2", "0", "0"] SDVT_VERSION = ["2", "0", "0"] SANDBOX_VERSION = ["2", "0", "0"] -NOR_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" -SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" -SANDBOX_APP_ID = "0x85d2fceef13a6c14c43527594f79fb91a8ef8f15024a43486efac8df2b11e632" AO_CONSENSUS_VERSION = 2 VEBO_CONSENSUS_VERSION = 2 diff --git a/scripts/vote_sr_v2_mainnet.py b/scripts/vote_sr_v2.py.template similarity index 81% rename from scripts/vote_sr_v2_mainnet.py rename to scripts/vote_sr_v2.py.template index 5101c85f5..5bc7502dc 100644 --- a/scripts/vote_sr_v2_mainnet.py +++ b/scripts/vote_sr_v2.py.template @@ -12,11 +12,14 @@ 10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo 11. Update `SimpleDVT` implementation 12. Finalize SimpleDVT upgrade -13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, -14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, -15. Grant manage consensus role to agent ${AGENT}` -16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` -17. Revoke manage consensus role from agent ${AGENT} +13. Publish new `Sandbox` implementation in Sandbox app APM repo +14. Update `Sandbox` implementation +15. Finalize Sandbox upgrade +16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, +17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +18. Grant manage consensus role to agent ${AGENT}` +19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +20. Revoke manage consensus role from agent ${AGENT}" """ import time @@ -33,14 +36,21 @@ get_deployer_account, get_is_live, contracts, + NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + SDVT_APP_ID, + SANDBOX_APP_ID, LIDO_LOCATOR_IMPL, STAKING_ROUTER_IMPL, - NODE_OPERATORS_REGISTRY_IMPL, ACCOUNTING_ORACLE_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, AGENT, ) -from utils.repo import add_implementation_to_nor_app_repo, add_implementation_to_sdvt_app_repo +from utils.repo import ( + add_implementation_to_nor_app_repo, + add_implementation_to_sdvt_app_repo, + add_implementation_to_sandbox_app_repo, +) from utils.kernel import update_app_implementation @@ -50,15 +60,14 @@ from utils.agent import agent_forward -PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000] -MAX_DEPOSITS_PER_BLOCK = [50, 50] -MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25] -NOR_VERSION = ["5", "0", "0"] -SDVT_VERSION = ["2", "0", "0"] -NOR_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" -SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" -AO_CONSENSUS_VERSION = 2 -VEBO_CONSENSUS_VERSION = 2 +PRIORITY_EXIT_SHARE_THRESHOLDS_BP= +MAX_DEPOSITS_PER_BLOCK = +MIN_DEPOSIT_BLOCK_DISTANCES = +NOR_VERSION = +SDVT_VERSION = +SANDBOX_VERSION = +AO_CONSENSUS_VERSION = +VEBO_CONSENSUS_VERSION = def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: @@ -88,6 +97,11 @@ def encode_sdvt_finalize() -> Tuple[str, str]: return proxy.address, proxy.finalizeUpgrade_v3.encode_input() +def encode_sandbox_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.sandbox) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: proxy = interface.OssifiableProxy(contracts.accounting_oracle) return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) @@ -118,9 +132,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T nor_repo = contracts.nor_app_repo.address simple_dvt_repo = contracts.simple_dvt_app_repo.address + sandbox_repo = contracts.sandbox_repo.address nor_uri = get_repo_uri(nor_repo) simple_dvt_uri = get_repo_uri(simple_dvt_repo) + sandbox_uri = get_repo_uri(sandbox_repo) call_script_items = [ # 1) @@ -181,10 +197,16 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # 12) encode_sdvt_finalize(), # 13) - agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), # 14) - encode_ao_finalize(), + update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), # 15) + encode_sandbox_finalize(), + # 16) + agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + # 17) + encode_ao_finalize(), + # 18) agent_forward( [ ( @@ -197,9 +219,9 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ) ] ), - # 16) + # 19) agent_forward([encode_set_consensus_version()]), - # 17) + # 20) agent_forward( [ ( @@ -227,11 +249,14 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", "11. Update `SimpleDVT` implementation", "12. Finalize SimpleDVT upgrade", - "13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", - "14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - "15. Grant manage consensus role to agent ${AGENT}", - "16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", - "17. Revoke manage consensus role from agent ${AGENT}", + "13. Publish new `Sandbox` implementation in Sandbox app APM repo", + "14. Update `Sandbox` implementation", + "15. Finalize Sandbox upgrade", + "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + "18. Grant manage consensus role to agent ${AGENT}", + "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + "20. Revoke manage consensus role from agent ${AGENT}", ] vote_items = bake_vote_items(vote_desc_items, call_script_items) @@ -246,7 +271,7 @@ def main(): tx_params["max_fee"] = "300 gwei" tx_params["priority_fee"] = "2 gwei" - print(f"tx = {tx_params}") + print(tx_params) vote_id, _ = start_vote(tx_params=tx_params, silent=False) From 7664d2b2eff63e85caa5914e62be1407f86a47bc Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 21 Jun 2024 12:38:41 +0400 Subject: [PATCH 012/220] fix: nor_app_id --- scripts/vote_sr_v2.py | 2 +- scripts/vote_sr_v2.py.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/vote_sr_v2.py b/scripts/vote_sr_v2.py index 695f38ff7..5dfd95b16 100644 --- a/scripts/vote_sr_v2.py +++ b/scripts/vote_sr_v2.py @@ -187,7 +187,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # 7) add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), # 8) - update_app_implementation(NOR_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), # 9) encode_nor_finalize(), # 10) diff --git a/scripts/vote_sr_v2.py.template b/scripts/vote_sr_v2.py.template index 5bc7502dc..65a8043a9 100644 --- a/scripts/vote_sr_v2.py.template +++ b/scripts/vote_sr_v2.py.template @@ -187,7 +187,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # 7) add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), # 8) - update_app_implementation(NOR_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), # 9) encode_nor_finalize(), # 10) From acb6d9fb360bd2d165da7f569c505c98bc692acf Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 21 Jun 2024 16:26:42 +0200 Subject: [PATCH 013/220] test: fix accounting oracle tests --- tests/acceptance/test_accounting_oracle.py | 2 +- .../test_accounting_oracle_negative.py | 73 +++---- utils/test/extra_data.py | 192 ++++++++++-------- utils/test/oracle_report_helpers.py | 16 +- 4 files changed, 156 insertions(+), 127 deletions(-) diff --git a/tests/acceptance/test_accounting_oracle.py b/tests/acceptance/test_accounting_oracle.py index 3be6bc2f5..8ac05306f 100644 --- a/tests/acceptance/test_accounting_oracle.py +++ b/tests/acceptance/test_accounting_oracle.py @@ -42,7 +42,7 @@ def test_constants(contract): def test_versioned(contract): - assert contract.getContractVersion() == 1 + assert contract.getContractVersion() == 2 def test_initialize(contract): diff --git a/tests/acceptance/test_accounting_oracle_negative.py b/tests/acceptance/test_accounting_oracle_negative.py index e1ee27e33..0e04d5030 100644 --- a/tests/acceptance/test_accounting_oracle_negative.py +++ b/tests/acceptance/test_accounting_oracle_negative.py @@ -1,4 +1,4 @@ -from typing import Callable +from typing import Callable, List from hexbytes import HexBytes from web3 import Web3 @@ -9,9 +9,10 @@ from utils.config import contracts, ACCOUNTING_ORACLE from utils.evm_script import encode_error -from utils.test.extra_data import ExtraDataService, ItemType +from utils.test.extra_data import ExtraDataService, ItemType, ExtraDataLengths from utils.test.oracle_report_helpers import ( ZERO_HASH, + ZERO_BYTES32, AccountingReport, oracle_report, EXTRA_DATA_FORMAT_EMPTY, @@ -19,7 +20,7 @@ ) NON_ZERO_HASH = ZERO_HASH[:-1] + b"\x01" -FIELDS_WIDTH = ExtraDataService.Lengths +FIELDS_WIDTH = ExtraDataLengths def test_sender_not_allowed(accounting_oracle: Contract, oracle_version: int, stranger: Account) -> None: @@ -176,82 +177,86 @@ def test_setConsensusContract(accounting_oracle: Contract, aragon_agent: Account class TestSubmitReportExtraDataList: + def build_extra_data(self, extra_data_items: List[bytes]) -> bytes: + return ZERO_BYTES32 + b"".join(extra_data_items) + + def test_too_short_extra_data_item(self): - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [2]), build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 2, [2], [2])[:36], - ) + ] ) with reverts(encode_error("InvalidExtraDataItem(uint256)", [1])): self.report(extra_data) - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2, 3, 4, 5], [2]), build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 2, [2], [2]), - ) + ] ) with reverts(encode_error("InvalidExtraDataItem(uint256)", [0])): self.report(extra_data) def test_nos_count_zero(self): - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [2]), build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 2, [], [1]), - ) + ] ) with reverts(encode_error("InvalidExtraDataItem(uint256)", [1])): self.report(extra_data) def test_module_id_zero(self): - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [2]), build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 0, [2], [1]), - ) + ] ) with reverts(encode_error("InvalidExtraDataItem(uint256)", [1])): self.report(extra_data) def test_unexpected_extra_data_index(self): - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [1]), build_extra_data_item(2, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 2, [2], [1]), - ) + ] ) with reverts(encode_error("UnexpectedExtraDataIndex(uint256,uint256)", [0, 1])): self.report(extra_data) - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [1]), build_extra_data_item(3, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [1]), - ) + ] ) with reverts(encode_error("UnexpectedExtraDataIndex(uint256,uint256)", [1, 3])): self.report(extra_data) - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [1]), build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [1]), - ) + ] ) with reverts(encode_error("UnexpectedExtraDataIndex(uint256,uint256)", [1, 0])): self.report(extra_data) def test_unsupported_extra_data_type(self): - extra_data = build_extra_data_item(0, ItemType.UNSUPPORTED, 1, [1], [1]) + extra_data = self.build_extra_data([build_extra_data_item(0, ItemType.UNSUPPORTED, 1, [1], [1])]) with reverts( encode_error( @@ -262,11 +267,11 @@ def test_unsupported_extra_data_type(self): self.report(extra_data, items_count=1) def test_invalid_extra_data_sort_order(self): - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [1]), build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [2], [1]), - ) + ] ) with reverts( @@ -277,11 +282,11 @@ def test_invalid_extra_data_sort_order(self): ): self.report(extra_data) - extra_data = b"".join( - ( + extra_data = self.build_extra_data( + [ build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [33], [250]), build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [33], [1]), - ) + ] ) with reverts( @@ -310,7 +315,7 @@ def test_unexpected_extra_data_item(self, extra_data_service: ExtraDataService) ) ): self.report( - extra_data.extra_data, + extra_data.extra_data_list[0], items_count=extra_data.items_count - 1, ) @@ -327,7 +332,7 @@ def test_already_processed( 1, ) - self.report(extra_data.extra_data, extra_data.items_count) + self.report(extra_data.extra_data_list[0], extra_data.items_count) with reverts(encode_error("ExtraDataAlreadyProcessed()")): accounting_oracle.submitReportExtraDataList(b"", {"from": consensus_member}) @@ -340,7 +345,7 @@ def report(self, extra_data: bytes, items_count: int = 2): extraDataHash=Web3.keccak(extra_data), extraDataItemsCount=items_count, extraDataFormat=EXTRA_DATA_FORMAT_LIST, - extraDataList=extra_data, + extraDataList=[extra_data], ) diff --git a/utils/test/extra_data.py b/utils/test/extra_data.py index 26563393e..743d8071f 100644 --- a/utils/test/extra_data.py +++ b/utils/test/extra_data.py @@ -1,7 +1,7 @@ -import itertools from dataclasses import dataclass +from itertools import groupby from enum import Enum -from typing import NewType, Tuple +from typing import List, NewType, Sequence, Tuple from hexbytes import HexBytes from brownie import web3 @@ -12,7 +12,6 @@ ZERO_HASH = bytes([0]*32) - class ItemType(Enum): EXTRA_DATA_TYPE_STUCK_VALIDATORS = 1 EXTRA_DATA_TYPE_EXITED_VALIDATORS = 2 @@ -41,129 +40,154 @@ class ExtraDataItem: @dataclass class ExtraData: - extra_data: bytes + extra_data_list: List[bytes] data_hash: HexBytes format: int items_count: int +@dataclass +class ItemPayload: + module_id: int + node_operator_ids: Sequence[int] + vals_counts: Sequence[int] + +class ExtraDataLengths: + NEXT_HASH = 32 + ITEM_INDEX = 3 + ITEM_TYPE = 2 + MODULE_ID = 3 + NODE_OPS_COUNT = 8 + NODE_OPERATOR_IDS = 8 + STUCK_OR_EXITED_VALS_COUNT = 16 + class ExtraDataService: """ Service that encodes extra data into bytes in correct order. + Extra data is an array of items, each item being encoded as follows: - | 3 bytes | 2 bytes | X bytes | - | itemIndex | itemType | itemPayload | + | 32 bytes | 3 bytes | 2 bytes | X bytes | + | nextHash | itemIndex | itemType | itemPayload | + itemPayload format: | 3 bytes | 8 bytes | nodeOpsCount * 8 bytes | nodeOpsCount * 16 bytes | | moduleId | nodeOpsCount | nodeOperatorIds | stuckOrExitedValsCount | + max_items_count - max itemIndex in extra data. max_no_in_payload_count - max nodeOpsCount that could be used in itemPayload. """ - - class Lengths: - ITEM_INDEX = 3 - ITEM_TYPE = 2 - MODULE_ID = 3 - NODE_OPS_COUNT = 8 - NODE_OPERATOR_IDS = 8 - STUCK_OR_EXITED_VALS_COUNT = 16 - + @classmethod def collect( - self, + cls, stuck_validators: dict[NodeOperatorGlobalIndex, int], exited_validators: dict[NodeOperatorGlobalIndex, int], max_items_count: int, max_no_in_payload_count: int, ) -> ExtraData: + stuck_payloads = cls.build_validators_payloads(stuck_validators, max_no_in_payload_count) + exited_payloads = cls.build_validators_payloads(exited_validators, max_no_in_payload_count) + items_count, txs = cls.build_extra_transactions_data(stuck_payloads, exited_payloads, max_items_count) + first_hash, hashed_txs = cls.add_hashes_to_transactions(txs) - stuck_payloads = self.build_validators_payloads( - stuck_validators, max_no_in_payload_count) - exited_payloads = self.build_validators_payloads( - exited_validators, max_no_in_payload_count) - - extra_data = self.build_extra_data( - stuck_payloads, exited_payloads, max_items_count) - extra_data_bytes = self.to_bytes(extra_data) - - if extra_data: - data_format = FormatList.EXTRA_DATA_FORMAT_LIST_NON_EMPTY - data_hash = web3.keccak(extra_data_bytes) + if items_count: + extra_data_format = FormatList.EXTRA_DATA_FORMAT_LIST_NON_EMPTY else: - data_format = FormatList.EXTRA_DATA_FORMAT_LIST_EMPTY - data_hash = HexBytes(ZERO_HASH) + extra_data_format = FormatList.EXTRA_DATA_FORMAT_LIST_EMPTY return ExtraData( - extra_data=extra_data_bytes, - data_hash=data_hash, - format=data_format.value, - items_count=len(extra_data), + items_count=items_count, + extra_data_list=hashed_txs, + data_hash=first_hash, + format=extra_data_format.value, ) - @staticmethod + @classmethod def build_validators_payloads( + cls, validators: dict[NodeOperatorGlobalIndex, int], max_no_in_payload_count: int, ) -> list[ItemPayload]: - # sort by module id and node operator id operator_validators = sorted(validators.items(), key=lambda x: x[0]) payloads = [] - for module_id, operators_by_module in itertools.groupby(operator_validators, key=lambda x: x[0][0]): - operator_ids = [] - vals_count = [] - - for ((_, no_id), validators_count) in list(operators_by_module)[:max_no_in_payload_count]: - operator_ids.append(no_id.to_bytes( - ExtraDataService.Lengths.NODE_OPERATOR_IDS, byteorder='big')) - vals_count.append(validators_count.to_bytes( - ExtraDataService.Lengths.STUCK_OR_EXITED_VALS_COUNT, byteorder='big')) - - payloads.append( - ItemPayload( - module_id=module_id.to_bytes( - ExtraDataService.Lengths.MODULE_ID, byteorder='big'), - node_ops_count=len(operator_ids).to_bytes( - ExtraDataService.Lengths.NODE_OPS_COUNT, byteorder='big'), - node_operator_ids=b"".join(operator_ids), - vals_counts=b"".join(vals_count), + for module_id, operators_by_module in groupby(operator_validators, key=lambda x: x[0][0]): + for nos_in_batch in cls.batch(list(operators_by_module), max_no_in_payload_count): + operator_ids = [] + vals_count = [] + + for ((_, no_id), validators_count) in nos_in_batch: + operator_ids.append(no_id) + vals_count.append(validators_count) + + payloads.append( + ItemPayload( + module_id=module_id, + node_operator_ids=operator_ids, + vals_counts=vals_count, + ) ) - ) return payloads - @staticmethod - def build_extra_data(stuck_payloads: list[ItemPayload], exited_payloads: list[ItemPayload], max_items_count: int): + @classmethod + def build_extra_transactions_data( + cls, + stuck_payloads: list[ItemPayload], + exited_payloads: list[ItemPayload], + max_items_count: int, + ) -> tuple[int, list[bytes]]: + all_payloads = [ + *[(ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, payload) for payload in stuck_payloads], + *[(ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, payload) for payload in exited_payloads], + ] + index = 0 - extra_data = [] - - for item_type, payloads in [ - (ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, stuck_payloads), - (ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, exited_payloads), - ]: - for payload in payloads: - extra_data.append(ExtraDataItem( - item_index=index.to_bytes( - ExtraDataService.Lengths.ITEM_INDEX, byteorder='big'), - item_type=item_type, - item_payload=payload - )) + result = [] + + for payload_batch in cls.batch(all_payloads, max_items_count): + tx = b'' + for item_type, payload in payload_batch: + tx += index.to_bytes(ExtraDataLengths.ITEM_INDEX, byteorder='big') + tx += item_type.value.to_bytes(ExtraDataLengths.ITEM_TYPE, byteorder='big') + tx += payload.module_id.to_bytes(ExtraDataLengths.MODULE_ID, byteorder='big') + tx += len(payload.node_operator_ids).to_bytes(ExtraDataLengths.NODE_OPS_COUNT, byteorder='big') + tx += b''.join( + no_id.to_bytes(ExtraDataLengths.NODE_OPERATOR_IDS, byteorder='big') + for no_id in payload.node_operator_ids + ) + tx += b''.join( + count.to_bytes(ExtraDataLengths.STUCK_OR_EXITED_VALS_COUNT, byteorder='big') + for count in payload.vals_counts + ) index += 1 - if index == max_items_count: - return extra_data - return extra_data + result.append(tx) + + return index, result + + @staticmethod + def add_hashes_to_transactions(txs_data: list[bytes]) -> tuple[bytes, list[bytes]]: + txs_data.reverse() + + txs_with_hashes = [] + next_hash = ZERO_HASH + + for tx in txs_data: + full_tx_data = next_hash + tx + txs_with_hashes.append(full_tx_data) + next_hash = web3.keccak(full_tx_data) + + txs_with_hashes.reverse() + + return next_hash, txs_with_hashes @staticmethod - def to_bytes(extra_data: list[ExtraDataItem]) -> bytes: - extra_data_bytes = b'' - for item in extra_data: - extra_data_bytes += item.item_index - extra_data_bytes += item.item_type.value.to_bytes( - ExtraDataService.Lengths.ITEM_TYPE, byteorder='big') - extra_data_bytes += item.item_payload.module_id - extra_data_bytes += item.item_payload.node_ops_count - extra_data_bytes += item.item_payload.node_operator_ids - extra_data_bytes += item.item_payload.vals_counts - return extra_data_bytes + def batch(iterable, n): + """ + Collect data into fixed-length chunks or blocks. + """ + length = len(iterable) + for ndx in range(0, length, n): + yield iterable[ndx:min(ndx + n, length)] diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index 78d35ea79..39a8a1b1d 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -1,6 +1,6 @@ import warnings from dataclasses import astuple, dataclass -from typing import Literal, overload +from typing import List, Literal, overload from brownie import chain, web3, accounts # type: ignore from brownie.exceptions import VirtualMachineError @@ -169,7 +169,7 @@ def push_oracle_report( extraDataHash=ZERO_BYTES32, extraDataItemsCount=0, silent=False, - extraDataList=b"", + extraDataList:List[bytes]=[], ): if not silent: print(f"Preparing oracle report for refSlot: {refSlot}") @@ -200,11 +200,11 @@ def push_oracle_report( print("Submitted report data") print(f"extraDataList {extraDataList}") if extraDataFormat == 0: - extra_report_tx = contracts.accounting_oracle.submitReportExtraDataEmpty({"from": submitter}) + extra_report_tx_list = [contracts.accounting_oracle.submitReportExtraDataEmpty({"from": submitter})] if not silent: print("Submitted empty extra data report") else: - extra_report_tx = contracts.accounting_oracle.submitReportExtraDataList(extraDataList, {"from": submitter}) + extra_report_tx_list = [contracts.accounting_oracle.submitReportExtraDataList(data, {"from": submitter}) for data in extraDataList] if not silent: print("Submitted NOT empty extra data report") @@ -228,7 +228,7 @@ def push_oracle_report( assert extraDataSubmitted assert state_extraDataItemsCount == extraDataItemsCount assert extraDataItemsSubmitted == extraDataItemsCount - return (report_tx, extra_report_tx) + return (report_tx, extra_report_tx_list) def simulate_report( @@ -295,7 +295,7 @@ def oracle_report( extraDataFormat=0, extraDataHash=ZERO_BYTES32, extraDataItemsCount=0, - extraDataList=b"", + extraDataList:List[bytes]=[], stakingModuleIdsWithNewlyExitedValidators=[], numExitedValidatorsByStakingModule=[], silent=False, @@ -323,7 +323,7 @@ def oracle_report( extraDataFormat=0, extraDataHash=ZERO_BYTES32, extraDataItemsCount=0, - extraDataList=b"", + extraDataList:List[bytes]=[], stakingModuleIdsWithNewlyExitedValidators=[], numExitedValidatorsByStakingModule=[], silent=False, @@ -351,7 +351,7 @@ def oracle_report( extraDataFormat=0, extraDataHash=ZERO_BYTES32, extraDataItemsCount=0, - extraDataList=b"", + extraDataList:List[bytes]=[], stakingModuleIdsWithNewlyExitedValidators=[], numExitedValidatorsByStakingModule=[], silent=False, From 2f64c0283fabd7de2cd1f563ff1206e837d15284 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 21 Jun 2024 19:15:05 +0400 Subject: [PATCH 014/220] fix: temp --- configs/config_holesky.py | 2 +- scripts/helpers/check.sh | 70 ----------------- scripts/helpers/check_holesky.py | 77 ------------------- scripts/helpers/check_mainnet.py | 69 ----------------- scripts/helpers/exec_voting.py | 68 ---------------- scripts/helpers/impersonate.py | 12 --- ...r_v2.py.template => vote_sr_v2_mainnet.py} | 58 +++++--------- .../vote_sr_v2.py => vote_sr_v2_holesky.py | 4 +- 8 files changed, 21 insertions(+), 339 deletions(-) delete mode 100755 scripts/helpers/check.sh delete mode 100644 scripts/helpers/check_holesky.py delete mode 100644 scripts/helpers/check_mainnet.py delete mode 100644 scripts/helpers/exec_voting.py delete mode 100644 scripts/helpers/impersonate.py rename scripts/{vote_sr_v2.py.template => vote_sr_v2_mainnet.py} (85%) rename scripts/vote_sr_v2.py => vote_sr_v2_holesky.py (98%) diff --git a/configs/config_holesky.py b/configs/config_holesky.py index c04708fed..5f120e76f 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -104,7 +104,7 @@ NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" -SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" +SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" SANDBOX_APP_ID = "0x85d2fceef13a6c14c43527594f79fb91a8ef8f15024a43486efac8df2b11e632" SIMPLE_DVT = "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6" diff --git a/scripts/helpers/check.sh b/scripts/helpers/check.sh deleted file mode 100755 index f92f68b5b..000000000 --- a/scripts/helpers/check.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -# Set RPC URL -RPC_URL="http://127.0.0.1:8555" - -# Locator address -LOCATOR_ADDRESS="0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -echo "Locator Address:" -cast call --rpc-url $RPC_URL $LOCATOR_ADDRESS "proxy__getImplementation()" --trace - -# Staking router implementation -STAKING_ROUTER="0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" -echo "Staking Router Implementation:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "proxy__getImplementation()" --trace - -# Pause role -PAUSE_ROLE="0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" -ADDRESS1="0x045dd46212A178428c088573A7d102B9d89a022A" -echo "Pause Role:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $PAUSE_ROLE $ADDRESS1 --trace - -# Resume role -RESUME_ROLE="0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" -echo "Resume Role:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $RESUME_ROLE $ADDRESS1 --trace - -# Unvetting role -UNVETTING_ROLE="0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" -ADDRESS2="0x389D2352b39962cE98D990a979639C1E07ed500f" -echo "Unvetting Role:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "hasRole(bytes32,address)(bool)" $UNVETTING_ROLE $ADDRESS2 --trace - -# SR version - -echo "staking router version:" -cast call --rpc-url $RPC_URL $STAKING_ROUTER "getContractVersion()(uint256)" --trace - - -# nor implementation was changed - -NOR="0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" - -echo "nor implemertation was changed" -cast call --rpc-url $RPC_URL $NOR "implementation()" --trace - -# nor version -echo "not version" -cast call --rpc-url $RPC_URL $NOR "getContractVersion()(uint256)" --trace - -# ao impl -AO=0x4E97A3972ce8511D87F334dA17a2C332542a5246 -echo "ao implementation" -cast call --rpc-url $RPC_URL $AO "proxy__getImplementation()" --trace - -echo "ao version" -cast call --rpc-url $RPC_URL $AO "getContractVersion()(uint256)" --trace - - -# vebo has MANAGE_CONSENSUS_VERSION_ROLE role - -MANAGE_CONSENSUS_VERSION_ROLE="0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" -VALIDATORS_EXIT_BUS_ORACLE="0xffDDF7025410412deaa05E3E1cE68FE53208afcb" -AGENT="0xE92329EC7ddB11D25e25b3c21eeBf11f15eB325d" -echo "vebo has MANAGE_CONSENSUS_VERSION_ROLE role:" -cast call --rpc-url $RPC_URL $VALIDATORS_EXIT_BUS_ORACLE "hasRole(bytes32,address)(bool)" $MANAGE_CONSENSUS_VERSION_ROLE $AGENT --trace - - -echo "VEBO getConsensusVersion" -cast call --rpc-url $RPC_URL $VALIDATORS_EXIT_BUS_ORACLE "getConsensusVersion()(uint256)" --trace - diff --git a/scripts/helpers/check_holesky.py b/scripts/helpers/check_holesky.py deleted file mode 100644 index 1175c9fd0..000000000 --- a/scripts/helpers/check_holesky.py +++ /dev/null @@ -1,77 +0,0 @@ -from brownie import network, Contract, accounts, rpc, chain - - -def main(): - # ABI of the contract (replace with actual ABI of your contract) - abi = [ - { - "inputs": [], - "name": "proxy__getImplementation", - "outputs": [{"internalType": "address", "name": "", "type": "address"}], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [], - "name": "implementation", - "outputs": [{"internalType": "address", "name": "", "type": "address"}], - "stateMutability": "view", - "type": "function", - }, - ] - - contract_address = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" - - contract = Contract.from_abi("LidoLocator", contract_address, abi) - - address = contract.proxy__getImplementation() - - # Print the transaction details - print(f"Locator impl: {address}") - - # Staking router implementation - STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" - - srAbi = [ - { - "inputs": [ - {"internalType": "bytes32", "name": "role", "type": "bytes32"}, - {"internalType": "address", "name": "account", "type": "address"}, - ], - "name": "hasRole", - "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], - "stateMutability": "view", - "type": "function", - } - ] - # Pause role - PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" - ADDRESS1 = "0x045dd46212A178428c088573A7d102B9d89a022A" - - sr = Contract.from_abi("StakingRouter", STAKING_ROUTER, srAbi) - res = sr.hasRole(PAUSE_ROLE, ADDRESS1) - - print(f"old dsm pause role: {res}") - - UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" - ADDRESS2 = "0xe0aA552A10d7EC8760Fc6c246D391E698a82dDf9" - - res2 = sr.hasRole(UNVETTING_ROLE, ADDRESS2) - - print(f"new dsm unvetting role: {res2}") - - sdvt_proxy = "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6" - sdvt = Contract.from_abi("SimpleDVT", sdvt_proxy, abi) - - sdvt_impl = sdvt.implementation() - - # Print the transaction details - print(f"Sdvt impl: {sdvt_impl}") - - sandbox_proxy_addr = "0xD6C2ce3BB8bea2832496Ac8b5144819719f343AC" - sandbox_proxy = Contract.from_abi("Sandbox", sandbox_proxy_addr, abi) - - sandbox_proxy_impl = sandbox_proxy.implementation() - - # Print the transaction details - print(f"Sandbox impl: {sandbox_proxy_impl }") diff --git a/scripts/helpers/check_mainnet.py b/scripts/helpers/check_mainnet.py deleted file mode 100644 index 15a6c640c..000000000 --- a/scripts/helpers/check_mainnet.py +++ /dev/null @@ -1,69 +0,0 @@ -from brownie import network, Contract, accounts, rpc, chain - - -def main(): - # ABI of the contract (replace with actual ABI of your contract) - abi = [ - { - "inputs": [], - "name": "proxy__getImplementation", - "outputs": [{"internalType": "address", "name": "", "type": "address"}], - "stateMutability": "view", - "type": "function", - }, - { - "inputs": [], - "name": "implementation", - "outputs": [{"internalType": "address", "name": "", "type": "address"}], - "stateMutability": "view", - "type": "function", - }, - ] - - contract_address = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" - - contract = Contract.from_abi("LidoLocator", contract_address, abi) - - address = contract.proxy__getImplementation() - - # Print the transaction details - print(f"Locator impl: {address}") - - # Staking router implementation - STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" - - srAbi = [ - { - "inputs": [ - {"internalType": "bytes32", "name": "role", "type": "bytes32"}, - {"internalType": "address", "name": "account", "type": "address"}, - ], - "name": "hasRole", - "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], - "stateMutability": "view", - "type": "function", - } - ] - # Pause role - PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" - ADDRESS1 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" - - sr = Contract.from_abi("StakingRouter", STAKING_ROUTER, srAbi) - res = sr.hasRole(PAUSE_ROLE, ADDRESS1) - - print(f"old dsm pause role: {res}") - - UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" - ADDRESS2 = "0xf9C8Cf55f2E520B08d869df7bc76aa3d3ddDF913" - - res2 = sr.hasRole(UNVETTING_ROLE, ADDRESS2) - - print(f"new dsm unvetting role: {res2}") - - sdvt_proxy = "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" - sdvt = Contract.from_abi("SimpleDVT", sdvt_proxy, abi) - - sdvt_impl = sdvt.implementation() - - # Print the transaction details - print(f"Sdvt impl: {sdvt_impl}") diff --git a/scripts/helpers/exec_voting.py b/scripts/helpers/exec_voting.py deleted file mode 100644 index 67b03f51c..000000000 --- a/scripts/helpers/exec_voting.py +++ /dev/null @@ -1,68 +0,0 @@ -from brownie import network, Contract, accounts, rpc, chain - - -def main(): - # ABI of the contract (replace with actual ABI of your contract) - abi = [ - { - "constant": False, - "inputs": [ - {"name": "_voteId", "type": "uint256"}, - {"name": "_supports", "type": "bool"}, - {"name": "_executesIfDecided_deprecated", "type": "bool"}, - ], - "name": "vote", - "outputs": [], - "payable": False, - "stateMutability": "nonpayable", - "type": "function", - }, - { - "constant": False, - "inputs": [{"name": "_voteId", "type": "uint256"}], - "name": "executeVote", - "outputs": [], - "payable": False, - "stateMutability": "nonpayable", - "type": "function", - }, - ] - # mainnet - account1 = accounts.at("0xb8d83908aab38a159f3da47a59d84db8e1838712", force=True) - account2 = accounts.at("0xa2dfc431297aee387c05beef507e5335e684fbcd", force=True) - vote_executor = "0x3e40d73eb977dc6a537af587d48316fee66e9c8c" - - сontract_address = "0x2e59A20f205bB85a89C53f1936454680651E618e" - - # holesky - # account1 = accounts.at("0xBA59A84C6440E8cccfdb5448877E26F1A431Fc8B", force=True) - # account2 = accounts.at("0x1D835790d93a28fb30d998C0CB27426E5D2D7C8c", force=True) - # vote_executor = "0xaa6bfBCD634EE744CB8FE522b29ADD23124593D3" - - # сontract_address = "0xdA7d2573Df555002503F29aA4003e398d28cc00f" - - contract = Contract.from_abi("Vote", сontract_address, abi) - - vote_id = 175 # Replace with the actual vote ID - supports = True # Set to True or False based on your requirement - executes_if_decided = False # Set to True or False based on your requirement - - contract.vote(vote_id, supports, executes_if_decided, {"from": account1}) - contract.vote(vote_id, supports, executes_if_decided, {"from": account2}) - - days = 3 - hours = 5 - total_sleep_time = (days * 24 * 60 * 60) + (hours * 60 * 60) # 3 days and 2 hours in seconds - - chain.sleep(total_sleep_time) - # Mine a block - chain.mine() - - tx = contract.executeVote(vote_id, {"from": vote_executor}) - - # Print the transaction details - print(f"Transaction hash: {tx.txid}") - print(f"Gas used: {tx.gas_used}") - - # Disconnect from the network - network.disconnect() diff --git a/scripts/helpers/impersonate.py b/scripts/helpers/impersonate.py deleted file mode 100644 index b5a3a72a9..000000000 --- a/scripts/helpers/impersonate.py +++ /dev/null @@ -1,12 +0,0 @@ -from brownie import accounts - - -def main(): - print(f"{accounts[0]}") - accounts.at(accounts[0], force=True) - # Address to impersonate - holder = "0xa2dfc431297aee387c05beef507e5335e684fbcd" - holder2 = "0xb8d83908aab38a159f3da47a59d84db8e1838712" - - accounts.at(holder, force=True) - accounts.at(holder2, force=True) diff --git a/scripts/vote_sr_v2.py.template b/scripts/vote_sr_v2_mainnet.py similarity index 85% rename from scripts/vote_sr_v2.py.template rename to scripts/vote_sr_v2_mainnet.py index 65a8043a9..0f81a5f07 100644 --- a/scripts/vote_sr_v2.py.template +++ b/scripts/vote_sr_v2_mainnet.py @@ -12,9 +12,6 @@ 10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo 11. Update `SimpleDVT` implementation 12. Finalize SimpleDVT upgrade -13. Publish new `Sandbox` implementation in Sandbox app APM repo -14. Update `Sandbox` implementation -15. Finalize Sandbox upgrade 16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, 17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, 18. Grant manage consensus role to agent ${AGENT}` @@ -37,8 +34,7 @@ get_is_live, contracts, NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, - SDVT_APP_ID, - SANDBOX_APP_ID, + SIMPLE_DVT_ARAGON_APP_ID, LIDO_LOCATOR_IMPL, STAKING_ROUTER_IMPL, ACCOUNTING_ORACLE_IMPL, @@ -49,7 +45,6 @@ from utils.repo import ( add_implementation_to_nor_app_repo, add_implementation_to_sdvt_app_repo, - add_implementation_to_sandbox_app_repo, ) from utils.kernel import update_app_implementation @@ -60,14 +55,13 @@ from utils.agent import agent_forward -PRIORITY_EXIT_SHARE_THRESHOLDS_BP= -MAX_DEPOSITS_PER_BLOCK = -MIN_DEPOSIT_BLOCK_DISTANCES = -NOR_VERSION = -SDVT_VERSION = -SANDBOX_VERSION = -AO_CONSENSUS_VERSION = -VEBO_CONSENSUS_VERSION = +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] +MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] +MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] +NOR_VERSION = ["2", "0", "0"] +SDVT_VERSION = ["2", "0", "0"] +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: @@ -97,11 +91,6 @@ def encode_sdvt_finalize() -> Tuple[str, str]: return proxy.address, proxy.finalizeUpgrade_v3.encode_input() -def encode_sandbox_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.sandbox) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: proxy = interface.OssifiableProxy(contracts.accounting_oracle) return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) @@ -132,11 +121,9 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T nor_repo = contracts.nor_app_repo.address simple_dvt_repo = contracts.simple_dvt_app_repo.address - sandbox_repo = contracts.sandbox_repo.address nor_uri = get_repo_uri(nor_repo) simple_dvt_uri = get_repo_uri(simple_dvt_repo) - sandbox_uri = get_repo_uri(sandbox_repo) call_script_items = [ # 1) @@ -193,20 +180,14 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # 10) add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), # 11) - update_app_implementation(SDVT_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), # 12) encode_sdvt_finalize(), # 13) - add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), - # 14) - update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 15) - encode_sandbox_finalize(), - # 16) agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), - # 17) + # 14) encode_ao_finalize(), - # 18) + # 15) agent_forward( [ ( @@ -219,9 +200,9 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ) ] ), - # 19) + # 16) agent_forward([encode_set_consensus_version()]), - # 20) + # 17) agent_forward( [ ( @@ -249,14 +230,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", "11. Update `SimpleDVT` implementation", "12. Finalize SimpleDVT upgrade", - "13. Publish new `Sandbox` implementation in Sandbox app APM repo", - "14. Update `Sandbox` implementation", - "15. Finalize Sandbox upgrade", - "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", - "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - "18. Grant manage consensus role to agent ${AGENT}", - "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", - "20. Revoke manage consensus role from agent ${AGENT}", + "13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + "14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + "15. Grant manage consensus role to agent ${AGENT}", + "16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + "17. Revoke manage consensus role from agent ${AGENT}", ] vote_items = bake_vote_items(vote_desc_items, call_script_items) diff --git a/scripts/vote_sr_v2.py b/vote_sr_v2_holesky.py similarity index 98% rename from scripts/vote_sr_v2.py rename to vote_sr_v2_holesky.py index 5dfd95b16..a73de64b1 100644 --- a/scripts/vote_sr_v2.py +++ b/vote_sr_v2_holesky.py @@ -37,7 +37,7 @@ get_is_live, contracts, NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, - SDVT_APP_ID, + SIMPLE_DVT_ARAGON_APP_ID, SANDBOX_APP_ID, LIDO_LOCATOR_IMPL, STAKING_ROUTER_IMPL, @@ -193,7 +193,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # 10) add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), # 11) - update_app_implementation(SDVT_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), # 12) encode_sdvt_finalize(), # 13) From ad7dba1c6a0a38cccd12da31d482c7b90bdb5579 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 21 Jun 2024 19:34:37 +0400 Subject: [PATCH 015/220] fix: script for mainnet vote --- scripts/vote_sr_v2_mainnet.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/vote_sr_v2_mainnet.py b/scripts/vote_sr_v2_mainnet.py index 0f81a5f07..20eec9293 100644 --- a/scripts/vote_sr_v2_mainnet.py +++ b/scripts/vote_sr_v2_mainnet.py @@ -55,10 +55,10 @@ from utils.agent import agent_forward -PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] -MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] -MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] -NOR_VERSION = ["2", "0", "0"] +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000] +MAX_DEPOSITS_PER_BLOCK = [50, 50] +MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25] +NOR_VERSION = ["5", "0", "0"] SDVT_VERSION = ["2", "0", "0"] AO_CONSENSUS_VERSION = 2 VEBO_CONSENSUS_VERSION = 2 From cfe0b596fefce81af156977df2dda72719386794 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 21 Jun 2024 19:48:38 +0400 Subject: [PATCH 016/220] fix: reset mainnet config --- configs/config_mainnet.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 984d59d96..12c28f062 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -98,7 +98,7 @@ # LidoLocator LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x832698Daec363C9A7aB036C224Af5B21280b3AC6" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" # set address here after SR V2 deploy # Other upgrade addresses LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" @@ -123,7 +123,7 @@ ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" # NodeOperatorsRegistry aka Curated Staking Module -NODE_OPERATORS_REGISTRY_IMPL = "0x4D1B781ce59B8C184F63B99D39d6719A522f46B5" # set address here after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" # set address here after SR V2 deploy ## see NodeOperatorsRegistry's proxy appId() NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY = 432000 @@ -186,7 +186,7 @@ TOTAL_COVER_SHARES_BURNT = 0 # DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0xf9C8Cf55f2E520B08d869df7bc76aa3d3ddDF913" # set address here after SR V2 deploy +DEPOSIT_SECURITY_MODULE = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact DSM_MAX_DEPOSITS_PER_BLOCK = 150 DSM_MIN_DEPOSIT_BLOCK_DISTANCE = 25 @@ -205,7 +205,7 @@ # AccountingOracle # and its corresponding HashConsensus ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0x654f70d8442EA18904FA1AD79114f7250F7E9336" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" # set address here after SR V2 deploy HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 @@ -252,7 +252,7 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" -STAKING_ROUTER_IMPL = "0xD22363efee93190f82b52FCD62B7Dbcb920eF658" # set address here after SR V2 deploy +STAKING_ROUTER_IMPL = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" # set address here after SR V2 deploy # Not a precise but still some estimation of the fees. Assume here that both modules are filled # SR_MODULES_FEE = curated_module_fee * (100% - sdvt_module_share) + sdvt_module_fee * sdvt_module_share From 33141554e3f1878d3495af7e47444c6795caedad Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 24 Jun 2024 12:41:34 +0400 Subject: [PATCH 017/220] fix: debug commit --- configs/config_holesky.py | 15 +- interfaces/Burner.json | 484 ++++- interfaces/csm/CSAccounting.json | 2088 +++++++++++++++++++ interfaces/csm/CSEarlyAdoption.json | 156 ++ interfaces/csm/CSFeeDistributor.json | 838 ++++++++ interfaces/csm/CSFeeOracle.json | 1268 +++++++++++ interfaces/csm/CSHashConsensus.json | 777 +++++++ interfaces/csm/CSModule.json | 1793 ++++++++++++++++ interfaces/csm/CSVerifier.json | 647 ++++++ scripts/{ => mainnet}/vote_sr_v2_mainnet.py | 0 scripts/vote_sr_v2_holesky.py | 386 ++++ utils/config.py | 10 + 12 files changed, 8456 insertions(+), 6 deletions(-) create mode 100644 interfaces/csm/CSAccounting.json create mode 100644 interfaces/csm/CSEarlyAdoption.json create mode 100644 interfaces/csm/CSFeeDistributor.json create mode 100644 interfaces/csm/CSFeeOracle.json create mode 100644 interfaces/csm/CSHashConsensus.json create mode 100644 interfaces/csm/CSModule.json create mode 100644 interfaces/csm/CSVerifier.json rename scripts/{ => mainnet}/vote_sr_v2_mainnet.py (100%) create mode 100644 scripts/vote_sr_v2_holesky.py diff --git a/configs/config_holesky.py b/configs/config_holesky.py index 5f120e76f..92abe1410 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -24,7 +24,7 @@ LEGACY_ORACLE = "0x072f72BE3AcFE2c52715829F2CD9061A6C8fF019" NODE_OPERATORS_REGISTRY = "0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" # set address here after deploy -NODE_OPERATORS_REGISTRY_IMPL = "0x6951b5Bd815043E3F842c1b026b0Fa888Cc2DD85" # set address here after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x4d75529C753eef6e18F2D37D13508FC5035Ec95e" # set address here after SR V2 deploy # Aragon APM Repos VOTING_REPO = "0x2997EA0D07D79038D83Cb04b3BB9A2Bc512E3fDA" @@ -78,20 +78,20 @@ LIDO_LOCATOR = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -LIDO_LOCATOR_IMPL = "0xcCB53c9429d32594F404d01fbe9E65ED1DCda8D9" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0xdcc2dD90186602f29Dfb0C8A65c9BD4d237090Ed" # set address here after SR V2 deploy WITHDRAWAL_QUEUE = "0xc7cc160b58F8Bb0baC94b80847E2CF2800565C50" ORACLE_DAEMON_CONFIG = "0xC01fC1F2787687Bc656EAc0356ba9Db6e6b7afb7" ORACLE_REPORT_SANITY_CHECKER = "0x7A4D8dF25f2A43505940232aC1397235899Fa8C" # set address here after SR V2 deploy BURNER = "0x4E46BD7147ccf666E1d73A3A456fC7a68de82eCA" -DEPOSIT_SECURITY_MODULE = "0xe0aA552A10d7EC8760Fc6c246D391E698a82dDf9" # set address here after SR V2 deploy +DEPOSIT_SECURITY_MODULE = "0x389D2352b39962cE98D990a979639C1E07ed500f" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0x045dd46212A178428c088573A7d102B9d89a022A" # dsm address before SR V2 enact ACCOUNTING_ORACLE = "0x4E97A3972ce8511D87F334dA17a2C332542a5246" -ACCOUNTING_ORACLE_IMPL = "0x6b4BDe1086912A6Cb24ce3dB43b3466e6c72AFd3" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0xFA6DD77332A32858f472c423d7fA79b99EEF386c" # set address here after SR V2 deploy VALIDATORS_EXIT_BUS_ORACLE = "0xffDDF7025410412deaa05E3E1cE68FE53208afcb" EIP712_STETH = "0xE154732c5Eab277fd88a9fF6Bdff7805eD97BCB1" STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" -STAKING_ROUTER_IMPL = "0xE7eD6747FaC5360f88a2EFC03E00d25789F69291" # set address here after SR V2 deploy +STAKING_ROUTER_IMPL = "0x38CE89269bF7145769a867F355B492a867e26Ab5" # set address here after SR V2 deploy WITHDRAWAL_VAULT_IMPL = "0xd517d9d04DA9B47dA23df91261bd3bF435BE964A" @@ -112,3 +112,8 @@ SANDBOX = "0xD6C2ce3BB8bea2832496Ac8b5144819719f343AC" SANDBOX_REPO = "0x00E75B5527a876B3F10C23436a0b896C626812d0" + + +CSM = "0x4562c3e63c2e586cD1651B958C22F88135aCAd4f" +CS_ACCOUNTING_ADDRESS = "0xc093e53e8F4b55A223c18A2Da6fA00e60DD5EFE1" +CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xbF38618Ea09B503c1dED867156A0ea276Ca1AE37" diff --git a/interfaces/Burner.json b/interfaces/Burner.json index e6ad32edc..ac643f234 100644 --- a/interfaces/Burner.json +++ b/interfaces/Burner.json @@ -1 +1,483 @@ -[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_stETH","type":"address"},{"internalType":"uint256","name":"_totalCoverSharesBurnt","type":"uint256"},{"internalType":"uint256","name":"_totalNonCoverSharesBurnt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AppAuthLidoFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"requestedAmount","type":"uint256"},{"internalType":"uint256","name":"actualAmount","type":"uint256"}],"name":"BurnAmountExceedsActual","type":"error"},{"inputs":[],"name":"DirectETHTransfer","type":"error"},{"inputs":[],"name":"StETHRecoveryWrongFunc","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroBurnAmount","type":"error"},{"inputs":[],"name":"ZeroRecoveryAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"ExcessStETHRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isCover","type":"bool"},{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"StETHBurnRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isCover","type":"bool"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"StETHBurnt","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REQUEST_BURN_MY_STETH_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REQUEST_BURN_SHARES_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sharesToBurn","type":"uint256"}],"name":"commitSharesToBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCoverSharesBurnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExcessStETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNonCoverSharesBurnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSharesRequestedToBurn","outputs":[{"internalType":"uint256","name":"coverShares","type":"uint256"},{"internalType":"uint256","name":"nonCoverShares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"recoverERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverExcessStETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stETHAmountToBurn","type":"uint256"}],"name":"requestBurnMyStETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stETHAmountToBurn","type":"uint256"}],"name":"requestBurnMyStETHForCover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_sharesAmountToBurn","type":"uint256"}],"name":"requestBurnShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_sharesAmountToBurn","type":"uint256"}],"name":"requestBurnSharesForCover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file +[ + { + "inputs": [ + { "internalType": "address", "name": "_admin", "type": "address" }, + { "internalType": "address", "name": "_treasury", "type": "address" }, + { "internalType": "address", "name": "_stETH", "type": "address" }, + { + "internalType": "uint256", + "name": "_totalCoverSharesBurnt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_totalNonCoverSharesBurnt", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "AppAuthLidoFailed", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requestedAmount", + "type": "uint256" + }, + { "internalType": "uint256", "name": "actualAmount", "type": "uint256" } + ], + "name": "BurnAmountExceedsActual", + "type": "error" + }, + { "inputs": [], "name": "DirectETHTransfer", "type": "error" }, + { "inputs": [], "name": "StETHRecoveryWrongFunc", "type": "error" }, + { + "inputs": [{ "internalType": "string", "name": "field", "type": "string" }], + "name": "ZeroAddress", + "type": "error" + }, + { "inputs": [], "name": "ZeroBurnAmount", "type": "error" }, + { "inputs": [], "name": "ZeroRecoveryAmount", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "requestedBy", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ERC20Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "requestedBy", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "requestedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfStETH", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfShares", + "type": "uint256" + } + ], + "name": "ExcessStETHRecovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bool", + "name": "isCover", + "type": "bool" + }, + { + "indexed": true, + "internalType": "address", + "name": "requestedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfStETH", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfShares", + "type": "uint256" + } + ], + "name": "StETHBurnRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bool", + "name": "isCover", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfStETH", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfShares", + "type": "uint256" + } + ], + "name": "StETHBurnt", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REQUEST_BURN_MY_STETH_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REQUEST_BURN_SHARES_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STETH", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TREASURY", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_sharesToBurn", "type": "uint256" } + ], + "name": "commitSharesToBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCoverSharesBurnt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getExcessStETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNonCoverSharesBurnt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleAdmin", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "getRoleMember", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleMemberCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSharesRequestedToBurn", + "outputs": [ + { "internalType": "uint256", "name": "coverShares", "type": "uint256" }, + { "internalType": "uint256", "name": "nonCoverShares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "recoverERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "recoverExcessStETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stETHAmountToBurn", + "type": "uint256" + } + ], + "name": "requestBurnMyStETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stETHAmountToBurn", + "type": "uint256" + } + ], + "name": "requestBurnMyStETHForCover", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_from", "type": "address" }, + { + "internalType": "uint256", + "name": "_sharesAmountToBurn", + "type": "uint256" + } + ], + "name": "requestBurnShares", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_from", "type": "address" }, + { + "internalType": "uint256", + "name": "_sharesAmountToBurn", + "type": "uint256" + } + ], + "name": "requestBurnSharesForCover", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/interfaces/csm/CSAccounting.json b/interfaces/csm/CSAccounting.json new file mode 100644 index 000000000..21c97ee94 --- /dev/null +++ b/interfaces/csm/CSAccounting.json @@ -0,0 +1,2088 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "lidoLocator", + "type": "address", + "internalType": "address" + }, + { + "name": "communityStakingModule", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "ACCOUNTING_MANAGER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ADD_BOND_CURVE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MAX_BOND_LOCK_RETENTION_PERIOD", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MIN_BOND_LOCK_RETENTION_PERIOD", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_INFINITELY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RECOVERER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RESET_BOND_CURVE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RESUME_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SET_BOND_CURVE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SET_DEFAULT_BOND_CURVE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addBondCurve", + "inputs": [ + { + "name": "bondCurve", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "chargeFee", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "chargeRecipient", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "claimRewardsStETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewardsWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "wstETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "compensateLockedBondETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "defaultBondCurveId", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "depositETH", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "depositStETH", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct CSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "depositWstETH", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "wstETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct CSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "feeDistributor", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSFeeDistributor" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getActualLockedBond", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBond", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondAmountByKeysCount", + "inputs": [ + { + "name": "keys", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curve", + "type": "tuple", + "internalType": "struct CSBondCurve.BondCurve", + "components": [ + { + "name": "id", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getBondAmountByKeysCount", + "inputs": [ + { + "name": "keys", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondAmountByKeysCountWstETH", + "inputs": [ + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curve", + "type": "tuple", + "internalType": "struct CSBondCurve.BondCurve", + "components": [ + { + "name": "id", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondAmountByKeysCountWstETH", + "inputs": [ + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondCurve", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct CSBondCurve.BondCurve", + "components": [ + { + "name": "id", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondLockRetentionPeriod", + "inputs": [], + "outputs": [ + { + "name": "retention", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondShares", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondSummary", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "current", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "required", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondSummaryShares", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "current", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "required", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getCurveInfo", + "inputs": [ + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct CSBondCurve.BondCurve", + "components": [ + { + "name": "id", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getKeysCountByBondAmount", + "inputs": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getKeysCountByBondAmount", + "inputs": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curve", + "type": "tuple", + "internalType": "struct CSBondCurve.BondCurve", + "components": [ + { + "name": "id", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getLockedBondInfo", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct CSBondLock.BondLock", + "components": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "retentionUntil", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRequiredBondForNextKeys", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "additionalKeys", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRequiredBondForNextKeysWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "additionalKeys", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getResumeSinceTimestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUnbondedKeysCount", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUnbondedKeysCountToEject", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "bondCurve", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "admin", + "type": "address", + "internalType": "address" + }, + { + "name": "_feeDistributor", + "type": "address", + "internalType": "address" + }, + { + "name": "bondLockRetentionPeriod", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_chargeRecipient", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isPaused", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lockBondETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pauseFor", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "penalize", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC1155", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC20", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC721", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverEther", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverStETHShares", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "releaseLockedBondETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "requestRewardsETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ethAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resetBondCurve", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resume", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setBondCurve", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setChargeRecipient", + "inputs": [ + { + "name": "_chargeRecipient", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setDefaultBondCurve", + "inputs": [ + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setLockedBondRetentionPeriod", + "inputs": [ + { + "name": "retention", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "settleLockedBondETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "lockedAmount", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalBondShares", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "BondBurned", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "toBurnAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "burnedAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondCharged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "toChargeAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "chargedAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondClaimed", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "to", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondClaimedWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "to", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondCurveAdded", + "inputs": [ + { + "name": "bondCurve", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondCurveChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "curveId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondDeposited", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "from", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondDepositedWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "from", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondLockChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "newAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "retentionUntil", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondLockCompensated", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondLockRetentionPeriodChanged", + "inputs": [ + { + "name": "retentionPeriod", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ChargeRecipientSet", + "inputs": [ + { + "name": "chargeRecipient", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DefaultBondCurveChanged", + "inputs": [ + { + "name": "curveId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Resumed", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "AlreadyInitialized", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondCurveId", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondCurveLength", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondCurveValues", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondLockAmount", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondLockRetentionPeriod", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidClaimableShares", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidSender", + "inputs": [] + }, + { + "type": "error", + "name": "NotAllowedToRecover", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "PauseUntilMustBeInFuture", + "inputs": [] + }, + { + "type": "error", + "name": "PausedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "ResumedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "SenderIsNotCSM", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAddress", + "inputs": [ + { + "name": "field", + "type": "string", + "internalType": "string" + } + ] + }, + { + "type": "error", + "name": "ZeroPauseDuration", + "inputs": [] + }, + { + "type": "event", + "name": "ERC1155Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC20Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC721Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EtherRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StETHSharesRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "AddressInsufficientBalance", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "FailedInnerCall", + "inputs": [] + }, + { + "type": "error", + "name": "FailedToSendEther", + "inputs": [] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + } +] \ No newline at end of file diff --git a/interfaces/csm/CSEarlyAdoption.json b/interfaces/csm/CSEarlyAdoption.json new file mode 100644 index 000000000..c538fd3eb --- /dev/null +++ b/interfaces/csm/CSEarlyAdoption.json @@ -0,0 +1,156 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_treeRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "_curveId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_module", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "consume", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "consumed", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "curveId", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isEligible", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "module", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "treeRoot", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "Consumed", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AlreadyConsumed", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidProof", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidValue", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyModule", + "inputs": [] + } +] \ No newline at end of file diff --git a/interfaces/csm/CSFeeDistributor.json b/interfaces/csm/CSFeeDistributor.json new file mode 100644 index 000000000..41b8377a4 --- /dev/null +++ b/interfaces/csm/CSFeeDistributor.json @@ -0,0 +1,838 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "stETH", + "type": "address", + "internalType": "address" + }, + { + "name": "accounting", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "ACCOUNTING", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ORACLE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RECOVERER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "STETH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IStETH" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "claimableShares", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "distributeFees", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "distributedShares", + "inputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getFeesToDistribute", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "hashLeaf", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "admin", + "type": "address", + "internalType": "address" + }, + { + "name": "oracle", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pendingToDistribute", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "processOracleReport", + "inputs": [ + { + "name": "_treeRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "_treeCid", + "type": "string", + "internalType": "string" + }, + { + "name": "distributed", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC1155", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC20", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC721", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverEther", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "treeCid", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "treeRoot", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "FeeDistributed", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidProof", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidShares", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidTreeCID", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidTreeRoot", + "inputs": [] + }, + { + "type": "error", + "name": "NotAccounting", + "inputs": [] + }, + { + "type": "error", + "name": "NotAllowedToRecover", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAddress", + "inputs": [ + { + "name": "field", + "type": "string", + "internalType": "string" + } + ] + }, + { + "type": "event", + "name": "ERC1155Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC20Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC721Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EtherRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StETHSharesRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "AddressInsufficientBalance", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "FailedInnerCall", + "inputs": [] + }, + { + "type": "error", + "name": "FailedToSendEther", + "inputs": [] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + } +] \ No newline at end of file diff --git a/interfaces/csm/CSFeeOracle.json b/interfaces/csm/CSFeeOracle.json new file mode 100644 index 000000000..b4470d5dc --- /dev/null +++ b/interfaces/csm/CSFeeOracle.json @@ -0,0 +1,1268 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "secondsPerSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "genesisTime", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "CONTRACT_MANAGER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GENESIS_TIME", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_CONSENSUS_CONTRACT_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_CONSENSUS_VERSION_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_INFINITELY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RECOVERER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RESUME_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SECONDS_PER_SLOT", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SUBMIT_DATA_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "discardConsensusReport", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "feeDistributor", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSFeeDistributor" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getConsensusContract", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getConsensusReport", + "inputs": [], + "outputs": [ + { + "name": "hash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "processingDeadlineTime", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "processingStarted", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getConsensusVersion", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getContractVersion", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLastProcessingRefSlot", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getResumeSinceTimestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "admin", + "type": "address", + "internalType": "address" + }, + { + "name": "feeDistributorContract", + "type": "address", + "internalType": "address" + }, + { + "name": "consensusContract", + "type": "address", + "internalType": "address" + }, + { + "name": "consensusVersion", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_perfThresholdBP", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isPaused", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "pauseFor", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pauseUntil", + "inputs": [ + { + "name": "pauseUntilInclusive", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "perfThresholdBP", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "recoverERC1155", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC20", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC721", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverEther", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resume", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setConsensusContract", + "inputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setConsensusVersion", + "inputs": [ + { + "name": "version", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setFeeDistributorContract", + "inputs": [ + { + "name": "feeDistributorContract", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setPerformanceThreshold", + "inputs": [ + { + "name": "valueBP", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "submitConsensusReport", + "inputs": [ + { + "name": "reportHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "submitReportData", + "inputs": [ + { + "name": "data", + "type": "tuple", + "internalType": "struct CSFeeOracle.ReportData", + "components": [ + { + "name": "consensusVersion", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "treeRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "treeCid", + "type": "string", + "internalType": "string" + }, + { + "name": "distributed", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "contractVersion", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "ConsensusHashContractSet", + "inputs": [ + { + "name": "addr", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "prevAddr", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ConsensusVersionSet", + "inputs": [ + { + "name": "version", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "prevVersion", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ContractVersionSet", + "inputs": [ + { + "name": "version", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeeDistributorContractSet", + "inputs": [ + { + "name": "feeDistributorContract", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PerformanceThresholdSet", + "inputs": [ + { + "name": "valueBP", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ProcessingStarted", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "hash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReportConsolidated", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "distributed", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newRoot", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "treeCid", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReportDiscarded", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "hash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReportSubmitted", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "hash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "processingDeadlineTime", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Resumed", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WarnProcessingMissed", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "AddressCannotBeSame", + "inputs": [] + }, + { + "type": "error", + "name": "AddressCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "AdminCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "HashCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "InitialRefSlotCannotBeLessThanProcessingOne", + "inputs": [ + { + "name": "initialRefSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "processingRefSlot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidContractVersionIncrement", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidPerfThreshold", + "inputs": [] + }, + { + "type": "error", + "name": "NoConsensusReportToProcess", + "inputs": [] + }, + { + "type": "error", + "name": "NonZeroContractVersionOnInit", + "inputs": [] + }, + { + "type": "error", + "name": "NotAllowedToRecover", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "PauseUntilMustBeInFuture", + "inputs": [] + }, + { + "type": "error", + "name": "PausedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "ProcessingDeadlineMissed", + "inputs": [ + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "RefSlotAlreadyProcessing", + "inputs": [] + }, + { + "type": "error", + "name": "RefSlotCannotDecrease", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "prevRefSlot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "RefSlotMustBeGreaterThanProcessingOne", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "processingRefSlot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ResumedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "SafeCastOverflowedUintDowncast", + "inputs": [ + { + "name": "bits", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "SecondsPerSlotCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "SenderIsNotTheConsensusContract", + "inputs": [] + }, + { + "type": "error", + "name": "SenderNotAllowed", + "inputs": [] + }, + { + "type": "error", + "name": "UnexpectedChainConfig", + "inputs": [] + }, + { + "type": "error", + "name": "UnexpectedConsensusVersion", + "inputs": [ + { + "name": "expectedVersion", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "receivedVersion", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "UnexpectedContractVersion", + "inputs": [ + { + "name": "expected", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "UnexpectedDataHash", + "inputs": [ + { + "name": "consensusHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "receivedHash", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "UnexpectedRefSlot", + "inputs": [ + { + "name": "consensusRefSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dataRefSlot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "VersionCannotBeSame", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroPauseDuration", + "inputs": [] + } +] \ No newline at end of file diff --git a/interfaces/csm/CSHashConsensus.json b/interfaces/csm/CSHashConsensus.json new file mode 100644 index 000000000..700bf2344 --- /dev/null +++ b/interfaces/csm/CSHashConsensus.json @@ -0,0 +1,777 @@ +[ + { + "inputs": [ + { "internalType": "uint256", "name": "slotsPerEpoch", "type": "uint256" }, + { + "internalType": "uint256", + "name": "secondsPerSlot", + "type": "uint256" + }, + { "internalType": "uint256", "name": "genesisTime", "type": "uint256" }, + { + "internalType": "uint256", + "name": "epochsPerFrame", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fastLaneLengthSlots", + "type": "uint256" + }, + { "internalType": "address", "name": "admin", "type": "address" }, + { + "internalType": "address", + "name": "reportProcessor", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "bytes32", "name": "neededRole", "type": "bytes32" } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { "inputs": [], "name": "AddressCannotBeZero", "type": "error" }, + { "inputs": [], "name": "AdminCannotBeZero", "type": "error" }, + { "inputs": [], "name": "ConsensusReportAlreadyProcessing", "type": "error" }, + { "inputs": [], "name": "DuplicateMember", "type": "error" }, + { "inputs": [], "name": "DuplicateReport", "type": "error" }, + { "inputs": [], "name": "EmptyReport", "type": "error" }, + { "inputs": [], "name": "EpochsPerFrameCannotBeZero", "type": "error" }, + { + "inputs": [], + "name": "FastLanePeriodCannotBeLongerThanFrame", + "type": "error" + }, + { "inputs": [], "name": "InitialEpochAlreadyArrived", "type": "error" }, + { "inputs": [], "name": "InitialEpochIsYetToArrive", "type": "error" }, + { + "inputs": [], + "name": "InitialEpochRefSlotCannotBeEarlierThanProcessingSlot", + "type": "error" + }, + { "inputs": [], "name": "InvalidChainConfig", "type": "error" }, + { "inputs": [], "name": "InvalidInitialization", "type": "error" }, + { "inputs": [], "name": "InvalidSlot", "type": "error" }, + { "inputs": [], "name": "NewProcessorCannotBeTheSame", "type": "error" }, + { + "inputs": [], + "name": "NonFastLaneMemberCannotReportWithinFastLaneInterval", + "type": "error" + }, + { "inputs": [], "name": "NonMember", "type": "error" }, + { "inputs": [], "name": "NotInitializing", "type": "error" }, + { "inputs": [], "name": "NumericOverflow", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "minQuorum", "type": "uint256" }, + { "internalType": "uint256", "name": "receivedQuorum", "type": "uint256" } + ], + "name": "QuorumTooSmall", + "type": "error" + }, + { "inputs": [], "name": "ReportProcessorCannotBeZero", "type": "error" }, + { + "inputs": [ + { "internalType": "uint8", "name": "bits", "type": "uint8" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { "inputs": [], "name": "StaleReport", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "expected", "type": "uint256" }, + { "internalType": "uint256", "name": "received", "type": "uint256" } + ], + "name": "UnexpectedConsensusVersion", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + } + ], + "name": "ConsensusLost", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "report", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "support", + "type": "uint256" + } + ], + "name": "ConsensusReached", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "fastLaneLengthSlots", + "type": "uint256" + } + ], + "name": "FastLaneConfigSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newInitialEpoch", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newEpochsPerFrame", + "type": "uint256" + } + ], + "name": "FrameConfigSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalMembers", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newQuorum", + "type": "uint256" + } + ], + "name": "MemberAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalMembers", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newQuorum", + "type": "uint256" + } + ], + "name": "MemberRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newQuorum", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalMembers", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "prevQuorum", + "type": "uint256" + } + ], + "name": "QuorumSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "processor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "prevProcessor", + "type": "address" + } + ], + "name": "ReportProcessorSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "member", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "report", + "type": "bytes32" + } + ], + "name": "ReportReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DISABLE_CONSENSUS_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_FAST_LANE_CONFIG_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_FRAME_CONFIG_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_MEMBERS_AND_QUORUM_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_REPORT_PROCESSOR_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "quorum", "type": "uint256" } + ], + "name": "addMember", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disableConsensus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getChainConfig", + "outputs": [ + { "internalType": "uint256", "name": "slotsPerEpoch", "type": "uint256" }, + { + "internalType": "uint256", + "name": "secondsPerSlot", + "type": "uint256" + }, + { "internalType": "uint256", "name": "genesisTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusState", + "outputs": [ + { "internalType": "uint256", "name": "refSlot", "type": "uint256" }, + { + "internalType": "bytes32", + "name": "consensusReport", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isReportProcessing", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "getConsensusStateForMember", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "currentFrameRefSlot", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "currentFrameConsensusReport", + "type": "bytes32" + }, + { "internalType": "bool", "name": "isMember", "type": "bool" }, + { "internalType": "bool", "name": "isFastLane", "type": "bool" }, + { "internalType": "bool", "name": "canReport", "type": "bool" }, + { + "internalType": "uint256", + "name": "lastMemberReportRefSlot", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "currentFrameMemberReport", + "type": "bytes32" + } + ], + "internalType": "struct HashConsensus.MemberConsensusState", + "name": "result", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentFrame", + "outputs": [ + { "internalType": "uint256", "name": "refSlot", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reportProcessingDeadlineSlot", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFastLaneMembers", + "outputs": [ + { "internalType": "address[]", "name": "addresses", "type": "address[]" }, + { + "internalType": "uint256[]", + "name": "lastReportedRefSlots", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFrameConfig", + "outputs": [ + { "internalType": "uint256", "name": "initialEpoch", "type": "uint256" }, + { + "internalType": "uint256", + "name": "epochsPerFrame", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fastLaneLengthSlots", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitialRefSlot", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "getIsFastLaneMember", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "getIsMember", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMembers", + "outputs": [ + { "internalType": "address[]", "name": "addresses", "type": "address[]" }, + { + "internalType": "uint256[]", + "name": "lastReportedRefSlots", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getQuorum", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReportProcessor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReportVariants", + "outputs": [ + { "internalType": "bytes32[]", "name": "variants", "type": "bytes32[]" }, + { "internalType": "uint256[]", "name": "support", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleAdmin", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "getRoleMember", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleMemberCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "quorum", "type": "uint256" } + ], + "name": "removeMember", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "fastLaneLengthSlots", + "type": "uint256" + } + ], + "name": "setFastLaneLengthSlots", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "epochsPerFrame", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fastLaneLengthSlots", + "type": "uint256" + } + ], + "name": "setFrameConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "quorum", "type": "uint256" } + ], + "name": "setQuorum", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newProcessor", "type": "address" } + ], + "name": "setReportProcessor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "slot", "type": "uint256" }, + { "internalType": "bytes32", "name": "report", "type": "bytes32" }, + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + } + ], + "name": "submitReport", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "initialEpoch", "type": "uint256" } + ], + "name": "updateInitialEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/interfaces/csm/CSModule.json b/interfaces/csm/CSModule.json new file mode 100644 index 000000000..c5bf6e454 --- /dev/null +++ b/interfaces/csm/CSModule.json @@ -0,0 +1,1793 @@ +[ + { + "inputs": [ + { "internalType": "bytes32", "name": "moduleType", "type": "bytes32" }, + { + "internalType": "uint256", + "name": "minSlashingPenaltyQuotient", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "elRewardsStealingFine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxKeysPerOperatorEA", + "type": "uint256" + }, + { "internalType": "address", "name": "lidoLocator", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "bytes32", "name": "neededRole", "type": "bytes32" } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { "inputs": [], "name": "AlreadyActivated", "type": "error" }, + { "inputs": [], "name": "AlreadySubmitted", "type": "error" }, + { "inputs": [], "name": "AlreadyWithdrawn", "type": "error" }, + { "inputs": [], "name": "EmptyKey", "type": "error" }, + { "inputs": [], "name": "ExitedKeysDecrease", "type": "error" }, + { + "inputs": [], + "name": "ExitedKeysHigherThanTotalDeposited", + "type": "error" + }, + { "inputs": [], "name": "InvalidAmount", "type": "error" }, + { "inputs": [], "name": "InvalidInitialization", "type": "error" }, + { "inputs": [], "name": "InvalidInput", "type": "error" }, + { "inputs": [], "name": "InvalidKeysCount", "type": "error" }, + { "inputs": [], "name": "InvalidLength", "type": "error" }, + { "inputs": [], "name": "InvalidReportData", "type": "error" }, + { "inputs": [], "name": "InvalidVetKeysPointer", "type": "error" }, + { "inputs": [], "name": "MaxSigningKeysCountExceeded", "type": "error" }, + { "inputs": [], "name": "NodeOperatorDoesNotExist", "type": "error" }, + { "inputs": [], "name": "NotAllowedToJoinYet", "type": "error" }, + { "inputs": [], "name": "NotAllowedToRecover", "type": "error" }, + { "inputs": [], "name": "NotEnoughKeys", "type": "error" }, + { "inputs": [], "name": "NotInitializing", "type": "error" }, + { "inputs": [], "name": "NotSupported", "type": "error" }, + { "inputs": [], "name": "PauseUntilMustBeInFuture", "type": "error" }, + { "inputs": [], "name": "PausedExpected", "type": "error" }, + { "inputs": [], "name": "QueueIsEmpty", "type": "error" }, + { "inputs": [], "name": "ResumedExpected", "type": "error" }, + { "inputs": [], "name": "SenderIsNotEligible", "type": "error" }, + { "inputs": [], "name": "SigningKeysInvalidOffset", "type": "error" }, + { "inputs": [], "name": "StuckKeysHigherThanNonExited", "type": "error" }, + { "inputs": [], "name": "ZeroAccountingAddress", "type": "error" }, + { "inputs": [], "name": "ZeroAdminAddress", "type": "error" }, + { "inputs": [], "name": "ZeroLocatorAddress", "type": "error" }, + { "inputs": [], "name": "ZeroPauseDuration", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "depositedKeysCount", + "type": "uint256" + } + ], + "name": "DepositedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ELRewardsStealingPenaltyCancelled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "proposedBlockHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stolenAmount", + "type": "uint256" + } + ], + "name": "ELRewardsStealingPenaltyReported", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + } + ], + "name": "ELRewardsStealingPenaltySettled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "exitedKeysCount", + "type": "uint256" + } + ], + "name": "ExitedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "keyIndex", + "type": "uint256" + } + ], + "name": "InitialSlashingSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "KeyRemovalChargeApplied", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "KeyRemovalChargeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "managerAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardAddress", + "type": "address" + } + ], + "name": "NodeOperatorAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "name": "NonceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "duration", + "type": "uint256" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "PublicRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "referrer", + "type": "address" + } + ], + "name": "ReferrerSet", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Resumed", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + } + ], + "name": "SigningKeyAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + } + ], + "name": "SigningKeyAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + } + ], + "name": "SigningKeyRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + } + ], + "name": "SigningKeyRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stuckKeysCount", + "type": "uint256" + } + ], + "name": "StuckSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "targetLimitMode", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "targetValidatorsCount", + "type": "uint256" + } + ], + "name": "TargetValidatorsCountChangedByRequest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalKeysCount", + "type": "uint256" + } + ], + "name": "TotalSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "vettedKeysCount", + "type": "uint256" + } + ], + "name": "VettedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "keyIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawalSubmitted", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EL_REWARDS_STEALING_FINE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIAL_SLASHING_PENALTY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LIDO_LOCATOR", + "outputs": [ + { "internalType": "contract ILidoLocator", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_SIGNING_KEYS_PER_OPERATOR_BEFORE_PUBLIC_RELEASE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MODULE_MANAGER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSE_INFINITELY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSE_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RECOVERER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REPORT_EL_REWARDS_STEALING_PENALTY_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESUME_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_ROUTER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STETH", + "outputs": [ + { "internalType": "contract IStETH", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERIFIER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accounting", + "outputs": [ + { + "internalType": "contract ICSAccounting", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activatePublicRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, + { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, + { "internalType": "bytes", "name": "signatures", "type": "bytes" }, + { + "internalType": "address", + "name": "managerAddress", + "type": "address" + }, + { "internalType": "address", "name": "rewardAddress", "type": "address" }, + { "internalType": "bytes32[]", "name": "eaProof", "type": "bytes32[]" }, + { "internalType": "address", "name": "referrer", "type": "address" } + ], + "name": "addNodeOperatorETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, + { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, + { "internalType": "bytes", "name": "signatures", "type": "bytes" }, + { + "internalType": "address", + "name": "managerAddress", + "type": "address" + }, + { "internalType": "address", "name": "rewardAddress", "type": "address" }, + { + "components": [ + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "internalType": "struct ICSAccounting.PermitInput", + "name": "permit", + "type": "tuple" + }, + { "internalType": "bytes32[]", "name": "eaProof", "type": "bytes32[]" }, + { "internalType": "address", "name": "referrer", "type": "address" } + ], + "name": "addNodeOperatorStETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, + { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, + { "internalType": "bytes", "name": "signatures", "type": "bytes" }, + { + "internalType": "address", + "name": "managerAddress", + "type": "address" + }, + { "internalType": "address", "name": "rewardAddress", "type": "address" }, + { + "components": [ + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "internalType": "struct ICSAccounting.PermitInput", + "name": "permit", + "type": "tuple" + }, + { "internalType": "bytes32[]", "name": "eaProof", "type": "bytes32[]" }, + { "internalType": "address", "name": "referrer", "type": "address" } + ], + "name": "addNodeOperatorWstETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, + { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, + { "internalType": "bytes", "name": "signatures", "type": "bytes" } + ], + "name": "addValidatorKeysETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, + { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, + { "internalType": "bytes", "name": "signatures", "type": "bytes" }, + { + "components": [ + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "internalType": "struct ICSAccounting.PermitInput", + "name": "permit", + "type": "tuple" + } + ], + "name": "addValidatorKeysStETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, + { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, + { "internalType": "bytes", "name": "signatures", "type": "bytes" }, + { + "components": [ + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "internalType": "struct ICSAccounting.PermitInput", + "name": "permit", + "type": "tuple" + } + ], + "name": "addValidatorKeysWstETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "cancelELRewardsStealingPenalty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "stETHAmount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "cumulativeFeeShares", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "rewardsProof", + "type": "bytes32[]" + } + ], + "name": "claimRewardsStETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "stEthAmount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "cumulativeFeeShares", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "rewardsProof", + "type": "bytes32[]" + } + ], + "name": "claimRewardsUnstETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "wstETHAmount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "cumulativeFeeShares", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "rewardsProof", + "type": "bytes32[]" + } + ], + "name": "claimRewardsWstETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "maxItems", "type": "uint256" } + ], + "name": "cleanDepositQueue", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "compensateELRewardsStealingPenalty", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "confirmNodeOperatorManagerAddressChange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "confirmNodeOperatorRewardAddressChange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "nodeOperatorIds", "type": "bytes" }, + { + "internalType": "bytes", + "name": "vettedSigningKeysCounts", + "type": "bytes" + } + ], + "name": "decreaseVettedSigningKeysCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "depositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositQueue", + "outputs": [ + { "internalType": "uint128", "name": "head", "type": "uint128" }, + { "internalType": "uint128", "name": "length", "type": "uint128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint128", "name": "index", "type": "uint128" } + ], + "name": "depositQueueItem", + "outputs": [{ "internalType": "Batch", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "stETHAmount", "type": "uint256" }, + { + "components": [ + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "internalType": "struct ICSAccounting.PermitInput", + "name": "permit", + "type": "tuple" + } + ], + "name": "depositStETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "wstETHAmount", "type": "uint256" }, + { + "components": [ + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "internalType": "struct ICSAccounting.PermitInput", + "name": "permit", + "type": "tuple" + } + ], + "name": "depositWstETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "earlyAdoption", + "outputs": [ + { + "internalType": "contract ICSEarlyAdoption", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getActiveNodeOperatorsCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "getNodeOperator", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "totalAddedKeys", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "totalWithdrawnKeys", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "totalDepositedKeys", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "totalVettedKeys", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "stuckValidatorsCount", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "depositableValidatorsCount", + "type": "uint32" + }, + { "internalType": "uint32", "name": "targetLimit", "type": "uint32" }, + { + "internalType": "uint8", + "name": "targetLimitMode", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "totalExitedKeys", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "enqueuedCount", + "type": "uint32" + }, + { + "internalType": "address", + "name": "managerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "proposedManagerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "proposedRewardAddress", + "type": "address" + } + ], + "internalType": "struct NodeOperator", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "offset", "type": "uint256" }, + { "internalType": "uint256", "name": "limit", "type": "uint256" } + ], + "name": "getNodeOperatorIds", + "outputs": [ + { + "internalType": "uint256[]", + "name": "nodeOperatorIds", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "getNodeOperatorIsActive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "getNodeOperatorNonWithdrawnKeys", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "getNodeOperatorSummary", + "outputs": [ + { + "internalType": "uint256", + "name": "targetLimitMode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNodeOperatorsCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNonce", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getResumeSinceTimestamp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleAdmin", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "getRoleMember", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleMemberCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "startIndex", "type": "uint256" }, + { "internalType": "uint256", "name": "keysCount", "type": "uint256" } + ], + "name": "getSigningKeys", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "startIndex", "type": "uint256" }, + { "internalType": "uint256", "name": "keysCount", "type": "uint256" } + ], + "name": "getSigningKeysWithSignatures", + "outputs": [ + { "internalType": "bytes", "name": "keys", "type": "bytes" }, + { "internalType": "bytes", "name": "signatures", "type": "bytes" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakingModuleSummary", + "outputs": [ + { + "internalType": "uint256", + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getType", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_accounting", "type": "address" }, + { + "internalType": "address", + "name": "_earlyAdoption", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_keyRemovalCharge", + "type": "uint256" + }, + { "internalType": "address", "name": "admin", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "keyIndex", "type": "uint256" } + ], + "name": "isValidatorSlashed", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "keyIndex", "type": "uint256" } + ], + "name": "isValidatorWithdrawn", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keyRemovalCharge", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "normalizeQueue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "depositsCount", "type": "uint256" }, + { "internalType": "bytes", "name": "", "type": "bytes" } + ], + "name": "obtainDepositData", + "outputs": [ + { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, + { "internalType": "bytes", "name": "signatures", "type": "bytes" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "onExitedAndStuckValidatorsCountsUpdated", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "totalShares", "type": "uint256" } + ], + "name": "onRewardsMinted", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "onWithdrawalCredentialsChanged", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "duration", "type": "uint256" } + ], + "name": "pauseFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "proposedAddress", + "type": "address" + } + ], + "name": "proposeNodeOperatorManagerAddressChange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "proposedAddress", + "type": "address" + } + ], + "name": "proposeNodeOperatorRewardAddressChange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "publicRelease", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "recoverERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "recoverERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "recoverEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "recoverStETHShares", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "startIndex", "type": "uint256" }, + { "internalType": "uint256", "name": "keysCount", "type": "uint256" } + ], + "name": "removeKeys", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "reportELRewardsStealingPenalty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } + ], + "name": "resetNodeOperatorManagerAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resume", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "setKeyRemovalCharge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "nodeOperatorIds", + "type": "uint256[]" + } + ], + "name": "settleELRewardsStealingPenalty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "keyIndex", "type": "uint256" } + ], + "name": "submitInitialSlashing", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "keyIndex", "type": "uint256" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "submitWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exitedValidatorsKeysCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stuckValidatorsKeysCount", + "type": "uint256" + } + ], + "name": "unsafeUpdateValidatorsCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "nodeOperatorIds", "type": "bytes" }, + { + "internalType": "bytes", + "name": "exitedValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateExitedValidatorsCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "updateRefundedValidatorsCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes", "name": "nodeOperatorIds", "type": "bytes" }, + { + "internalType": "bytes", + "name": "stuckValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateStuckValidatorsCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "targetLimitMode", + "type": "uint256" + }, + { "internalType": "uint256", "name": "targetLimit", "type": "uint256" } + ], + "name": "updateTargetValidatorsLimits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/interfaces/csm/CSVerifier.json b/interfaces/csm/CSVerifier.json new file mode 100644 index 000000000..d8ce7029d --- /dev/null +++ b/interfaces/csm/CSVerifier.json @@ -0,0 +1,647 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "slotsPerEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "gIHistoricalSummaries", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "gIFirstWithdrawal", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "gIFirstValidator", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "firstSupportedSlot", + "type": "uint64", + "internalType": "Slot" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "BEACON_ROOTS", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "FIRST_SUPPORTED_SLOT", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "Slot" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_FIRST_VALIDATOR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_FIRST_WITHDRAWAL", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_HISTORICAL_SUMMARIES", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SLOTS_PER_EPOCH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_locator", + "type": "address", + "internalType": "address" + }, + { + "name": "_module", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "locator", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ILidoLocator" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "module", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSModule" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "processHistoricalWithdrawalProof", + "inputs": [ + { + "name": "beaconBlock", + "type": "tuple", + "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", + "components": [ + { + "name": "header", + "type": "tuple", + "internalType": "struct BeaconBlockHeader", + "components": [ + { + "name": "slot", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "proposerIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "parentRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "stateRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bodyRoot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "rootsTimestamp", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "name": "oldBlock", + "type": "tuple", + "internalType": "struct ICSVerifier.HistoricalHeaderWitness", + "components": [ + { + "name": "header", + "type": "tuple", + "internalType": "struct BeaconBlockHeader", + "components": [ + { + "name": "slot", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "proposerIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "parentRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "stateRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bodyRoot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "rootGIndex", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ] + }, + { + "name": "witness", + "type": "tuple", + "internalType": "struct ICSVerifier.WithdrawalWitness", + "components": [ + { + "name": "withdrawalOffset", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "withdrawalIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "validatorIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalCredentials", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "effectiveBalance", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "slashed", + "type": "bool", + "internalType": "bool" + }, + { + "name": "activationEligibilityEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "activationEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "exitEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawableEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "validatorProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ] + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "processSlashingProof", + "inputs": [ + { + "name": "beaconBlock", + "type": "tuple", + "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", + "components": [ + { + "name": "header", + "type": "tuple", + "internalType": "struct BeaconBlockHeader", + "components": [ + { + "name": "slot", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "proposerIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "parentRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "stateRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bodyRoot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "rootsTimestamp", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "name": "witness", + "type": "tuple", + "internalType": "struct ICSVerifier.SlashingWitness", + "components": [ + { + "name": "validatorIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalCredentials", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "effectiveBalance", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "activationEligibilityEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "activationEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "exitEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawableEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "validatorProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ] + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "processWithdrawalProof", + "inputs": [ + { + "name": "beaconBlock", + "type": "tuple", + "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", + "components": [ + { + "name": "header", + "type": "tuple", + "internalType": "struct BeaconBlockHeader", + "components": [ + { + "name": "slot", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "proposerIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "parentRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "stateRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bodyRoot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "rootsTimestamp", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "name": "witness", + "type": "tuple", + "internalType": "struct ICSVerifier.WithdrawalWitness", + "components": [ + { + "name": "withdrawalOffset", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "withdrawalIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "validatorIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalCredentials", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "effectiveBalance", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "slashed", + "type": "bool", + "internalType": "bool" + }, + { + "name": "activationEligibilityEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "activationEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "exitEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawableEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "validatorProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ] + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "error", + "name": "IndexOutOfRange", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBlockHeader", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidChainConfig", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidGIndex", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidWithdrawalAddress", + "inputs": [] + }, + { + "type": "error", + "name": "PartialWitdrawal", + "inputs": [] + }, + { + "type": "error", + "name": "RootNotFound", + "inputs": [] + }, + { + "type": "error", + "name": "UnsupportedSlot", + "inputs": [ + { + "name": "slot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ValidatorNotWithdrawn", + "inputs": [] + }, + { + "type": "error", + "name": "BranchHasExtraItem", + "inputs": [] + }, + { + "type": "error", + "name": "BranchHasMissingItem", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidProof", + "inputs": [] + } +] \ No newline at end of file diff --git a/scripts/vote_sr_v2_mainnet.py b/scripts/mainnet/vote_sr_v2_mainnet.py similarity index 100% rename from scripts/vote_sr_v2_mainnet.py rename to scripts/mainnet/vote_sr_v2_mainnet.py diff --git a/scripts/vote_sr_v2_holesky.py b/scripts/vote_sr_v2_holesky.py new file mode 100644 index 000000000..01109352e --- /dev/null +++ b/scripts/vote_sr_v2_holesky.py @@ -0,0 +1,386 @@ +""" +SR V2 +1. Update locator implementation +2. Revoke pause role from old DSM +3. Revoke resume role from old DSM +4. Grant unvetting role to new DSM +5. Update SR implementation +6. Call finalize upgrade on SR +7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo +8. Update `NodeOperatorsRegistry` implementation +9. Finalize NOR upgrade +10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo +11. Update `SimpleDVT` implementation +12. Finalize SimpleDVT upgrade +13. Publish new `Sandbox` implementation in Sandbox app APM repo +14. Update `Sandbox` implementation +15. Finalize Sandbox upgrade +16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, +17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +18. Grant manage consensus role to agent ${AGENT}` +19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +20. Revoke manage consensus role from agent ${AGENT}" + +CSM + +21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE +22. Add staking module +23. Grant request burn role to CSAccounting contract +24. Grant resume role to agent +25. Resume staking module +26. Revoke resume role from agent +27. Update initial epoch +28. Add CS settle EL stealing factory to ET +29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} +""" + +import time + +try: + from brownie import interface, accounts +except ImportError: + print("You're probably running inside Brownie console. Please call:") + print("set_console_globals(interface=interface)") + + +from typing import Dict, Tuple, Optional +from utils.config import ( + get_deployer_account, + get_is_live, + contracts, + NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + SIMPLE_DVT_ARAGON_APP_ID, + SANDBOX_APP_ID, + LIDO_LOCATOR_IMPL, + STAKING_ROUTER_IMPL, + ACCOUNTING_ORACLE_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, + CS_ACCOUNTING_ADDRESS, + AGENT, + CS_ORACLE_HASH_CONSENSUS_ADDRESS, +) + +from utils.repo import ( + add_implementation_to_nor_app_repo, + add_implementation_to_sdvt_app_repo, + add_implementation_to_sandbox_app_repo, +) + +from utils.kernel import update_app_implementation + +from utils.voting import bake_vote_items, confirm_vote_script, create_vote + +from brownie.network.transaction import TransactionReceipt +from utils.agent import agent_forward + +# SR +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] +MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] +MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] +NOR_VERSION = ["2", "0", "0"] +SDVT_VERSION = ["2", "0", "0"] +SANDBOX_VERSION = ["2", "0", "0"] +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 + +# CSM + +CS_MODULE_NAME = "CommunityStaking" +CS_STAKE_SHARE_LIMIT = 2000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 +CS_STAKING_MODULE_FEE = 800 +CS_TREASURY_FEE = 200 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 58050 + + +def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.lido_locator) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_staking_router_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.staking_router) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_staking_router_finalize() -> Tuple[str, str]: + proxy = interface.StakingRouter(contracts.staking_router) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input( + PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES + ) + + +def encode_nor_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.node_operators_registry) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_sdvt_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.simple_dvt) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_sandbox_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.sandbox) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.accounting_oracle) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_ao_finalize() -> Tuple[str, str]: + proxy = interface.AccountingOracle(contracts.accounting_oracle) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) + + +def encode_set_consensus_version() -> Tuple[str, str]: + proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) + return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) + + +def get_repo_uri(repo_address: str) -> str: + contract = interface.Repo(repo_address).getLatest() + return contract["contentURI"] + + +def get_repo_version(repo_address: str) -> tuple[int, int, int]: + contract = interface.Repo(repo_address).getLatest() + return contract["semanticVersion"] + + +def grantCsmResumeRoleToAgent() -> Tuple[str, str]: + + return ( + contracts.csm.address, + contracts.csm.grantRole.encode_input( + # keccak256 RESUME_ROLE + "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7", + contracts.agent.address, + ), + ) + + +def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: + """Prepare and run voting.""" + + nor_repo = contracts.nor_app_repo.address + simple_dvt_repo = contracts.simple_dvt_app_repo.address + sandbox_repo = contracts.sandbox_repo.address + + nor_uri = get_repo_uri(nor_repo) + simple_dvt_uri = get_repo_uri(simple_dvt_repo) + sandbox_uri = get_repo_uri(sandbox_repo) + + call_script_items = [ + # SR 2 + # 1) + # agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), + # # 2) + # agent_forward( + # [ + # ( + # contracts.staking_router.address, + # contracts.staking_router.revokeRole.encode_input( + # # keccak256 STAKING_MODULE_PAUSE_ROLE + # "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", + # contracts.deposit_security_module_v2, + # ), + # ) + # ] + # ), + # 3) + # agent_forward( + # [ + # ( + # contracts.staking_router.address, + # contracts.staking_router.revokeRole.encode_input( + # # keccak256 STAKING_MODULE_RESUME_ROLE + # "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", + # contracts.deposit_security_module_v2, + # ), + # ) + # ] + # ), + # # 4) + # agent_forward( + # [ + # ( + # contracts.staking_router.address, + # contracts.staking_router.grantRole.encode_input( + # # keccak256 STAKING_MODULE_UNVETTING_ROLE + # "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", + # contracts.deposit_security_module, + # ), + # ) + # ] + # ), + # 5) + # agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), + # # 6) + # encode_staking_router_finalize(), + # # 7) + # add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), + # # 8) + # update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # # 9) + # encode_nor_finalize(), + # # 10) + # add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), + # # 11) + # update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # # 12) + # encode_sdvt_finalize(), + # # 13) + # add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), + # # 14) + # update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # # 15) + # encode_sandbox_finalize(), + # # 16) + # agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + # # 17) + # encode_ao_finalize(), + # 18) + # agent_forward( + # [ + # ( + # contracts.validators_exit_bus_oracle.address, + # contracts.validators_exit_bus_oracle.grantRole.encode_input( + # # keccak256 MANAGE_CONSENSUS_VERSION_ROLE + # "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", + # contracts.agent.address, + # ), + # ) + # ] + # ), + # # 19) + # agent_forward([encode_set_consensus_version()]), + # # 20) + # agent_forward( + # [ + # ( + # contracts.validators_exit_bus_oracle.address, + # contracts.validators_exit_bus_oracle.revokeRole.encode_input( + # # keccak256 MANAGE_CONSENSUS_VERSION_ROLE + # "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", + # contracts.agent.address, + # ), + # ) + # ] + # ), + # CSM + # 21) + # agent_forward( + # [ + # ( + # contracts.staking_router.address, + # contracts.staking_router.grantRole.encode_input( + # # STAKING_MODULE_MANAGE_ROLE + # "0x3105bcbf19d4417b73ae0e58d508a65ecf75665e46c2622d8521732de6080c48", + # contracts.agent.address, + # ), + # ) + # ] + # ), + # 22) + # agent_forward( + # [ + # ( + # contracts.staking_router.address, + # contracts.staking_router.addStakingModule.encode_input( + # CS_MODULE_NAME, + # contracts.csm.address, + # CS_STAKE_SHARE_LIMIT, + # CS_PRIORITY_EXIT_SHARE_THRESHOLD, + # CS_STAKING_MODULE_FEE, + # CS_TREASURY_FEE, + # CS_MAX_DEPOSITS_PER_BLOCK, + # CS_MIN_DEPOSIT_BLOCK_DISTANCE, + # ), + # ), + # ] + # ), + # 23) + # agent_forward( + # [ + # ( + # contracts.burner.address, + # contracts.burner.grantRole.encode_input( + # # keccak256 'REQUEST_BURN_SHARES_ROLE' + # "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8", + # CS_ACCOUNTING_ADDRESS, + # ), + # ) + # ] + # ), + # 24) + agent_forward([grantCsmResumeRoleToAgent()]), + # # 25) + # agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), + # # 26) + # ( + # contracts.csm.address, + # contracts.csm.revokeRole.encode_input( + # "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7", contracts.agent.address + # ), + # ), + # # 27) + # (contracts.csmHashConsensus.address, contracts.csmHashConsensus.updateInitialEpoch(CS_ORACLE_INITIAL_EPOCH)), + # 28) + ] + + vote_desc_items = [ + # "1. Update locator implementation", + # "2. Revoke pause role from old DSM", + # "3. Revoke resume role from old DSM", + # "4. Grant unvetting role to new DSM", + # "5. Update SR implementation", + # "6. Call finalize upgrade on SR", + # "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + # "8. Update `NodeOperatorsRegistry` implementation", + # "9. Finalize NOR upgrade", + # "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", + # "11. Update `SimpleDVT` implementation", + # "12. Finalize SimpleDVT upgrade", + # "13. Publish new `Sandbox` implementation in Sandbox app APM repo", + # "14. Update `Sandbox` implementation", + # "15. Finalize Sandbox upgrade", + # "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + # "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + # "18. Grant manage consensus role to agent ${AGENT}", + # "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + # "20. Revoke manage consensus role from agent ${AGENT}", + # "21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE", + # "22. Add staking module", + # "23. Grant request burn role to CSAccounting contract", + "24. Grant resume role to agent", + # "25. Resume staking module", + # "26. Revoke resume role from agent", + # "27. Update initial epoch", + # 28. Add CS settle EL stealing factory to ET + # 29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} + ] + + vote_items = bake_vote_items(vote_desc_items, call_script_items) + + return confirm_vote_script(vote_items, silent) and list(create_vote(vote_items, tx_params)) + + +def main(): + tx_params = {"from": get_deployer_account()} + + if get_is_live(): + tx_params["max_fee"] = "300 gwei" + tx_params["priority_fee"] = "2 gwei" + + print(tx_params) + + vote_id, _ = start_vote(tx_params=tx_params, silent=False) + + vote_id >= 0 and print(f"Vote created: {vote_id}.") + + time.sleep(10) # hack for waiting thread #2. diff --git a/utils/config.py b/utils/config.py index 3a4261701..ba8c18927 100644 --- a/utils/config.py +++ b/utils/config.py @@ -9,6 +9,8 @@ from brownie.utils import color from brownie.network.account import Account, LocalAccount +from brownie import Contract, web3 + MAINNET_VOTE_DURATION = 3 * 24 * 60 * 60 @@ -173,6 +175,14 @@ def node_operators_registry(self) -> interface.NodeOperatorsRegistry: def simple_dvt(self) -> interface.SimpleDVT: return interface.SimpleDVT(SIMPLE_DVT) + @property + def csm(self) -> interface.CSModule: + return interface.CSModule(CSM) + + @property + def csmHashConsensus(self) -> interface.CSHashConsensus: + return interface.CSHashConsensus(CS_ORACLE_HASH_CONSENSUS_ADDRESS) + @property def sandbox(self) -> interface.SimpleDVT: return interface.Sandbox(SANDBOX) From 44f5be6ccab8013676afa0f0b8e9f7fb8d4dbc95 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 24 Jun 2024 13:31:21 +0200 Subject: [PATCH 018/220] test: fix test_accounting_oracle_extra_data_full_items --- ...accounting_oracle_extra_data_full_items.py | 27 ++++++++++++------- utils/test/node_operators_helpers.py | 18 +++++++++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 8f2481738..a92059b5c 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -8,12 +8,12 @@ from utils.test.helpers import shares_balance, almostEqWithDiff from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch from utils.test.oracle_report_helpers import oracle_report +from utils.test.node_operators_helpers import distribute_reward from utils.config import MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT from utils.config import contracts from utils.test.simple_dvt_helpers import simple_dvt_add_node_operators, simple_dvt_add_keys, simple_dvt_vet_keys - @pytest.fixture() def extra_data_service(): return ExtraDataService() @@ -127,17 +127,20 @@ def test_extra_data_full_items( sdvt_balance_shares_before.append(shares_balance(sdvt.getNodeOperator(i, False)["rewardAddress"])) # Perform report - (report_tx, extra_report_tx) = oracle_report( + (report_tx, _) = oracle_report( extraDataFormat=1, extraDataHash=extra_data.data_hash, extraDataItemsCount=(nor_exited_items + nor_stuck_items + sdvt_exited_items + sdvt_stuck_items), - extraDataList=extra_data.extra_data, + extraDataList=extra_data.extra_data_list, stakingModuleIdsWithNewlyExitedValidators=modules_with_exited, numExitedValidatorsByStakingModule=num_exited_validators_by_staking_module, ) - penalty_shares = 0 + nor_distribute_reward_tx = distribute_reward(nor) + sdvt_distribute_reward_tx = distribute_reward(sdvt) + # Check NOR exited + nor_penalty_shares = 0 for i in range(0, len(nor_exited)): assert nor.getNodeOperatorSummary(i)["totalExitedValidators"] == nor_exited[(1, i)] # Check NOR stuck. Check penalties and rewards @@ -155,9 +158,13 @@ def test_extra_data_full_items( rewards_after // 2, 1, ) - penalty_shares += rewards_after // 2 + nor_penalty_shares += rewards_after // 2 + + if nor_penalty_shares > 0: + assert almostEqWithDiff(sum(e['amountOfShares'] for e in nor_distribute_reward_tx.events["StETHBurnRequested"]), nor_penalty_shares, 50) # Check SDVT exited + sdvt_penalty_shares = 0 for i in range(0, len(sdvt_exited)): assert sdvt.getNodeOperatorSummary(i)["totalExitedValidators"] == sdvt_exited[(2, i)] # Check SDVT stuck. Check penalties and rewards @@ -175,11 +182,12 @@ def test_extra_data_full_items( rewards_after // 2, 1, ) - penalty_shares += rewards_after // 2 + sdvt_penalty_shares += rewards_after // 2 + - if penalty_shares > 0: + if sdvt_penalty_shares > 0: # TODO: Fix below check when contains other penalized node operators - assert almostEqWithDiff(sum(e['amountOfShares'] for e in extra_report_tx.events["StETHBurnRequested"]), penalty_shares, 100) + assert almostEqWithDiff(sum(e['amountOfShares'] for e in sdvt_distribute_reward_tx.events["StETHBurnRequested"]), sdvt_penalty_shares, 50) ############################################ # HELPER FUNCTIONS @@ -274,8 +282,7 @@ def deposit_buffer_for_keys(staking_router, sdvt_keys_to_deposit, nor_keys_to_de total_depositable_keys = 0 module_digests = staking_router.getAllStakingModuleDigests() for digest in module_digests: - (_, _, state, summary) = digest - (id, _, _, _, target_share, status, _, _, _, _) = state + (_, _, _, summary) = digest (exited_keys, deposited_keys, depositable_keys) = summary total_depositable_keys += depositable_keys diff --git a/utils/test/node_operators_helpers.py b/utils/test/node_operators_helpers.py index af01b1892..efc28252f 100644 --- a/utils/test/node_operators_helpers.py +++ b/utils/test/node_operators_helpers.py @@ -4,6 +4,8 @@ from typing import Dict, List from eth_abi import encode from typing import NewType, Tuple +from utils.config import contracts +from enum import Enum SIGNING_KEY_KEYS = ["key", "depositSignature", "used"] @@ -34,6 +36,11 @@ NodeOperatorId = NewType("NodeOperatorId", int) NodeOperatorGlobalIndex = Tuple[StakingModuleId, NodeOperatorId] +class RewardDistributionState(Enum): + TransferredToModule = 0 # New reward portion minted and transferred to the module + ReadyForDistribution = 1 # Operators' statistics updated, reward ready for distribution + Distributed = 2 # Reward distributed among operators + def node_operator_gindex(module_id, node_operator_id) -> NodeOperatorGlobalIndex: return module_id, node_operator_id @@ -92,3 +99,14 @@ def get_event_log(tx: network.transaction.TransactionReceipt, event_signature: s assert log is not None, f'Topic for event "{event_signature}" not found' return log + +def distribute_reward(nor): + rewardDistributionState = nor.getRewardDistributionState() + assert rewardDistributionState == RewardDistributionState.ReadyForDistribution.value, "Reward is not ready for distribution" + + tx = nor.distributeReward({"from": contracts.voting}) + + rewardDistributionState = nor.getRewardDistributionState() + assert rewardDistributionState == RewardDistributionState.Distributed.value, "Reward distribution failed" + + return tx From 25b5adba96aef6b833d7656601f4f2f7759f32ae Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 24 Jun 2024 14:57:42 +0200 Subject: [PATCH 019/220] test: fix test_accounting_oracle_extra_data --- tests/regression/test_accounting_oracle_extra_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/regression/test_accounting_oracle_extra_data.py b/tests/regression/test_accounting_oracle_extra_data.py index dcdf0808e..689c8d894 100644 --- a/tests/regression/test_accounting_oracle_extra_data.py +++ b/tests/regression/test_accounting_oracle_extra_data.py @@ -30,5 +30,5 @@ def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): extraDataFormat=1, extraDataHash=extra_data.data_hash, extraDataItemsCount=item_count, - extraDataList=extra_data.extra_data, + extraDataList=extra_data.extra_data_list, ) From 9d24e88e14f59610b23d970b8f64b9f3535fc12a Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 24 Jun 2024 15:35:27 +0200 Subject: [PATCH 020/220] test: test_accounting_oracle_extra_data_full_items distribute reward from stranger address --- .../test_accounting_oracle_extra_data_full_items.py | 4 ++-- utils/test/node_operators_helpers.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index a92059b5c..a9ee3a8fb 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -136,8 +136,8 @@ def test_extra_data_full_items( numExitedValidatorsByStakingModule=num_exited_validators_by_staking_module, ) - nor_distribute_reward_tx = distribute_reward(nor) - sdvt_distribute_reward_tx = distribute_reward(sdvt) + nor_distribute_reward_tx = distribute_reward(nor, stranger) + sdvt_distribute_reward_tx = distribute_reward(sdvt, stranger) # Check NOR exited nor_penalty_shares = 0 diff --git a/utils/test/node_operators_helpers.py b/utils/test/node_operators_helpers.py index efc28252f..554125f7a 100644 --- a/utils/test/node_operators_helpers.py +++ b/utils/test/node_operators_helpers.py @@ -4,7 +4,6 @@ from typing import Dict, List from eth_abi import encode from typing import NewType, Tuple -from utils.config import contracts from enum import Enum SIGNING_KEY_KEYS = ["key", "depositSignature", "used"] @@ -100,11 +99,11 @@ def get_event_log(tx: network.transaction.TransactionReceipt, event_signature: s assert log is not None, f'Topic for event "{event_signature}" not found' return log -def distribute_reward(nor): +def distribute_reward(nor, from_address): rewardDistributionState = nor.getRewardDistributionState() assert rewardDistributionState == RewardDistributionState.ReadyForDistribution.value, "Reward is not ready for distribution" - tx = nor.distributeReward({"from": contracts.voting}) + tx = nor.distributeReward({"from": from_address}) rewardDistributionState = nor.getRewardDistributionState() assert rewardDistributionState == RewardDistributionState.Distributed.value, "Reward distribution failed" From 2a65987acb4983476d1c65ed0bfcc6af166dbbcc Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 24 Jun 2024 16:21:30 +0200 Subject: [PATCH 021/220] test: fix test_all_round_happy_path --- tests/regression/test_all_round_happy_path.py | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tests/regression/test_all_round_happy_path.py b/tests/regression/test_all_round_happy_path.py index a692d895f..6996c8653 100644 --- a/tests/regression/test_all_round_happy_path.py +++ b/tests/regression/test_all_round_happy_path.py @@ -1,6 +1,7 @@ import math from brownie import ZERO_ADDRESS, chain +from utils.test.node_operators_helpers import distribute_reward from utils.test.oracle_report_helpers import oracle_report from utils.test.helpers import ETH, almostEqEth from utils.config import contracts @@ -157,7 +158,10 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): treasury_balance_before_rebase = contracts.lido.sharesOf(treasury) - report_tx, extra_tx = oracle_report(cl_diff=ETH(100)) + report_tx = oracle_report(cl_diff=ETH(100))[0] + + nor_distribute_reward_tx = distribute_reward(contracts.node_operators_registry, stranger) + sdvt_distribute_reward_tx = distribute_reward(contracts.simple_dvt, stranger) steth_balance_after_rebase = contracts.lido.balanceOf(stranger) treasury_balance_after_rebase = contracts.lido.sharesOf(treasury) @@ -181,14 +185,23 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): if len(penalized_node_operator_ids_sdvt) > 0: expected_burner_transfers += 1 - for e in extra_tx.events["Transfer"]: + for e in nor_distribute_reward_tx.events["Transfer"]: + if e["to"] == contracts.burner: + burner_transfers += 1 + for e in sdvt_distribute_reward_tx.events["Transfer"]: if e["to"] == contracts.burner: burner_transfers += 1 + assert burner_transfers == expected_burner_transfers assert ( - extra_tx.events.count("Transfer") == expected_transfers_count_nor + expected_transfers_count_sdvt - ), "extra_tx.events should have Transfer to all active operators (+1 optional to Burner), check activity condition above" + nor_distribute_reward_tx.events.count("Transfer") == expected_transfers_count_nor + ), "nor_distribute_reward_tx.events should have Transfer to all active operators (+1 optional to Burner), check activity condition above" + + assert ( + sdvt_distribute_reward_tx.events.count("Transfer") == expected_transfers_count_sdvt + ), "sdvt_distribute_reward_tx.events should have Transfer to all active operators (+1 optional to Burner), check activity condition above" + assert report_tx.events.count("TokenRebased") == 1 assert report_tx.events.count("WithdrawalsFinalized") == 1 assert report_tx.events.count("StETHBurnt") == 1 @@ -277,7 +290,7 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): ) locked_ether_amount_before_finalization = contracts.withdrawal_queue.getLockedEtherAmount() - report_tx, _ = oracle_report(cl_diff=ETH(100)) + report_tx = oracle_report(cl_diff=ETH(100))[0] locked_ether_amount_after_finalization = contracts.withdrawal_queue.getLockedEtherAmount() withdrawal_finalized_event = report_tx.events["WithdrawalsFinalized"] From f2473f3889809ca086ec42c4355063c5ed6b1992 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 25 Jun 2024 12:30:06 +0200 Subject: [PATCH 022/220] test: fix sanity checker --- .../test_oracle_report_sanity_checker.py | 6 +++-- tests/regression/test_sanity_checks.py | 27 ++++++++++++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/tests/acceptance/test_oracle_report_sanity_checker.py b/tests/acceptance/test_oracle_report_sanity_checker.py index 667198936..fa8c4bd5c 100644 --- a/tests/acceptance/test_oracle_report_sanity_checker.py +++ b/tests/acceptance/test_oracle_report_sanity_checker.py @@ -4,7 +4,8 @@ from utils.config import ( contracts, ORACLE_REPORT_SANITY_CHECKER, - CHURN_VALIDATORS_PER_DAY_LIMIT, + EXITED_VALIDATORS_PER_DAY_LIMIT, + APPEARED_VALIDATORS_PER_DAY_LIMIT, ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT, ANNUAL_BALANCE_INCREASE_BP_LIMIT, SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT, @@ -17,7 +18,7 @@ # Source of truth: https://hackmd.io/pdix1r4yR46fXUqiHaNKyw?view report_limits = { - "churnValidatorsPerDayLimit": CHURN_VALIDATORS_PER_DAY_LIMIT, + "exitedValidatorsPerDayLimit": EXITED_VALIDATORS_PER_DAY_LIMIT, "oneOffCLBalanceDecreaseBPLimit": ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT, "annualBalanceIncreaseBPLimit": ANNUAL_BALANCE_INCREASE_BP_LIMIT, "simulatedShareRateDeviationBPLimit": SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT, @@ -26,6 +27,7 @@ "maxNodeOperatorsPerExtraDataItemCount": MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT, "requestTimestampMargin": REQUEST_TIMESTAMP_MARGIN, "maxPositiveTokenRebase": MAX_POSITIVE_TOKEN_REBASE, + "appearedValidatorsPerDayLimit": APPEARED_VALIDATORS_PER_DAY_LIMIT, } diff --git a/tests/regression/test_sanity_checks.py b/tests/regression/test_sanity_checks.py index aa99fdcdc..40e42186a 100644 --- a/tests/regression/test_sanity_checks.py +++ b/tests/regression/test_sanity_checks.py @@ -14,7 +14,8 @@ from utils.test.helpers import ETH, eth_balance from utils.config import ( contracts, - CHURN_VALIDATORS_PER_DAY_LIMIT, + APPEARED_VALIDATORS_PER_DAY_LIMIT, + EXITED_VALIDATORS_PER_DAY_LIMIT, ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT, ANNUAL_BALANCE_INCREASE_BP_LIMIT, MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT, @@ -80,7 +81,7 @@ def test_too_large_cl_increase_with_appeared_validator(pre_cl_balance): def test_too_much_validators_appeared(): - deposited_validators = CHURN_VALIDATORS_PER_DAY_LIMIT + 1 + deposited_validators = APPEARED_VALIDATORS_PER_DAY_LIMIT + 1 fake_deposited_validators_increase(deposited_validators) with reverts(encode_error("IncorrectAppearedValidators(uint256)", [deposited_validators])): @@ -98,11 +99,11 @@ def test_too_much_validators_exited(): with reverts( encode_error( "ExitedValidatorsLimitExceeded(uint256,uint256)", - [CHURN_VALIDATORS_PER_DAY_LIMIT, CHURN_VALIDATORS_PER_DAY_LIMIT + 1], + [EXITED_VALIDATORS_PER_DAY_LIMIT, EXITED_VALIDATORS_PER_DAY_LIMIT + 1], ) ): oracle_report( - numExitedValidatorsByStakingModule=[CHURN_VALIDATORS_PER_DAY_LIMIT + previously_exited + 1], + numExitedValidatorsByStakingModule=[EXITED_VALIDATORS_PER_DAY_LIMIT + previously_exited + 1], stakingModuleIdsWithNewlyExitedValidators=[1], skip_withdrawals=True, silent=True, @@ -211,7 +212,19 @@ def test_report_deviated_simulated_share_rate(steth_holder): def test_accounting_oracle_too_much_extra_data(extra_data_service): item_count = MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT + 1 - extra_data = extra_data_service.collect({(1, 1): 1}, {}, 1, 1) + + operators = {} + nor_module_id = 1 + nor_operators_count = contracts.node_operators_registry.getNodeOperatorsCount() + i = 0 + while len(operators) < item_count and i < nor_operators_count: + (active, _, _, _, total_exited_validators_count, _, _) = contracts.node_operators_registry.getNodeOperator(i, True) + if(active): + operators[(nor_module_id, i)] = total_exited_validators_count + 1 + i = i + 1 + + extra_data = extra_data_service.collect({}, operators, item_count, 1) + with reverts( encode_error( "MaxAccountingExtraDataItemsCountExceeded(uint256,uint256)", @@ -222,7 +235,7 @@ def test_accounting_oracle_too_much_extra_data(extra_data_service): extraDataFormat=1, extraDataHash=extra_data.data_hash, extraDataItemsCount=item_count, - extraDataList=extra_data.extra_data, + extraDataList=extra_data.extra_data_list, ) @@ -240,7 +253,7 @@ def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): extraDataFormat=1, extraDataHash=extra_data.data_hash, extraDataItemsCount=1, - extraDataList=extra_data.extra_data, + extraDataList=extra_data.extra_data_list, ) From 2106f303141490ddc12799a30bda6452ac696b6f Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Tue, 25 Jun 2024 16:11:50 +0400 Subject: [PATCH 023/220] feat: voting tests --- interfaces/SimpleDVT.json | 1635 +++++++++++++++++++++++++++++- tests/test_vote_sr_v2_mainnet.py | 464 +++++++++ 2 files changed, 2098 insertions(+), 1 deletion(-) create mode 100644 tests/test_vote_sr_v2_mainnet.py diff --git a/interfaces/SimpleDVT.json b/interfaces/SimpleDVT.json index 632231338..bbff81661 100644 --- a/interfaces/SimpleDVT.json +++ b/interfaces/SimpleDVT.json @@ -1 +1,1634 @@ -[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_keysCount","type":"uint256"},{"name":"_publicKeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getType","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"clearNodeOperatorPenalty","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_offset","type":"uint256"},{"name":"_limit","type":"uint256"}],"name":"getNodeOperatorIds","outputs":[{"name":"nodeOperatorIds","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_offset","type":"uint256"},{"name":"_limit","type":"uint256"}],"name":"getSigningKeys","outputs":[{"name":"pubkeys","type":"bytes"},{"name":"signatures","type":"bytes"},{"name":"used","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fromIndex","type":"uint256"},{"name":"_keysCount","type":"uint256"}],"name":"removeSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorIsActive","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_name","type":"string"}],"name":"setNodeOperatorName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_totalRewardShares","type":"uint256"}],"name":"getRewardsDistribution","outputs":[{"name":"recipients","type":"address[]"},{"name":"shares","type":"uint256[]"},{"name":"penalized","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_indexFrom","type":"uint256"},{"name":"_indexTo","type":"uint256"}],"name":"invalidateReadyToDepositKeysRange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_locator","type":"address"},{"name":"_type","type":"bytes32"},{"name":"_stuckPenaltyDelay","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_delay","type":"uint256"}],"name":"setStuckPenaltyDelay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStuckPenaltyDelay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fromIndex","type":"uint256"},{"name":"_keysCount","type":"uint256"}],"name":"removeSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"isOperatorPenalized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"deactivateNodeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"STAKING_ROUTER_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_keysCount","type":"uint256"},{"name":"_publicKeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getActiveNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_rewardAddress","type":"address"}],"name":"addNodeOperator","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getContractVersion","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getUnusedSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"onRewardsMinted","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_NODE_OPERATOR_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"onWithdrawalCredentialsChanged","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"activateNodeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_rewardAddress","type":"address"}],"name":"setNodeOperatorRewardAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fullInfo","type":"bool"}],"name":"getNodeOperator","outputs":[{"name":"active","type":"bool"},{"name":"name","type":"string"},{"name":"rewardAddress","type":"address"},{"name":"totalVettedValidators","type":"uint64"},{"name":"totalExitedValidators","type":"uint64"},{"name":"totalAddedValidators","type":"uint64"},{"name":"totalDepositedValidators","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_locator","type":"address"},{"name":"_type","type":"bytes32"},{"name":"_stuckPenaltyDelay","type":"uint256"}],"name":"finalizeUpgrade_v2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStakingModuleSummary","outputs":[{"name":"totalExitedValidators","type":"uint256"},{"name":"totalDepositedValidators","type":"uint256"},{"name":"depositableValidatorsCount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorIds","type":"bytes"},{"name":"_exitedValidatorsCounts","type":"bytes"}],"name":"updateExitedValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorIds","type":"bytes"},{"name":"_stuckValidatorsCounts","type":"bytes"}],"name":"updateStuckValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_refundedValidatorsCount","type":"uint256"}],"name":"updateRefundedValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_isTargetLimitActive","type":"bool"},{"name":"_targetLimit","type":"uint256"}],"name":"updateTargetValidatorsLimits","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_vettedSigningKeysCount","type":"uint64"}],"name":"setNodeOperatorStakingLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorSummary","outputs":[{"name":"isTargetLimitActive","type":"bool"},{"name":"targetValidatorsCount","type":"uint256"},{"name":"stuckValidatorsCount","type":"uint256"},{"name":"refundedValidatorsCount","type":"uint256"},{"name":"stuckPenaltyEndTimestamp","type":"uint256"},{"name":"totalExitedValidators","type":"uint256"},{"name":"totalDepositedValidators","type":"uint256"},{"name":"depositableValidatorsCount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"getSigningKey","outputs":[{"name":"key","type":"bytes"},{"name":"depositSignature","type":"bytes"},{"name":"used","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NODE_OPERATOR_NAME_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_depositsCount","type":"uint256"},{"name":"","type":"bytes"}],"name":"obtainDepositData","outputs":[{"name":"publicKeys","type":"bytes"},{"name":"signatures","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getKeysOpIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNonce","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLocator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SET_NODE_OPERATOR_LIMIT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getTotalSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_STUCK_PENALTY_DELAY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"onExitedAndStuckValidatorsCountsUpdated","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NODE_OPERATORS_COUNT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKeyOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_exitedValidatorsCount","type":"uint256"},{"name":"_stuckValidatorsCount","type":"uint256"}],"name":"unsafeUpdateValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_SIGNING_KEYS","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"isOperatorPenaltyCleared","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"stakingLimit","type":"uint64"}],"name":"NodeOperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"NodeOperatorActiveSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"name","type":"string"}],"name":"NodeOperatorNameSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"rewardAddress","type":"address"}],"name":"NodeOperatorRewardAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"totalKeysTrimmed","type":"uint64"}],"name":"NodeOperatorTotalKeysTrimmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"keysOpIndex","type":"uint256"}],"name":"KeysOpIndexSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"moduleType","type":"bytes32"}],"name":"StakingModuleTypeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"sharesAmount","type":"uint256"}],"name":"RewardsDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"locatorAddress","type":"address"}],"name":"LocatorContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"approvedValidatorsCount","type":"uint256"}],"name":"VettedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"depositedValidatorsCount","type":"uint256"}],"name":"DepositedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"exitedValidatorsCount","type":"uint256"}],"name":"ExitedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"totalValidatorsCount","type":"uint256"}],"name":"TotalSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nonce","type":"uint256"}],"name":"NonceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"stuckPenaltyDelay","type":"uint256"}],"name":"StuckPenaltyDelayChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"stuckValidatorsCount","type":"uint256"},{"indexed":false,"name":"refundedValidatorsCount","type":"uint256"},{"indexed":false,"name":"stuckPenaltyEndTimestamp","type":"uint256"}],"name":"StuckPenaltyStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"targetValidatorsCount","type":"uint256"}],"name":"TargetValidatorsCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipientAddress","type":"address"},{"indexed":false,"name":"sharesPenalizedAmount","type":"uint256"}],"name":"NodeOperatorPenalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}] \ No newline at end of file +[ + { + "constant": true, + "inputs": [], + "name": "hasInitialized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_targetLimitMode", + "type": "uint256" + }, + { + "name": "_targetLimit", + "type": "uint256" + } + ], + "name": "updateTargetValidatorsLimits", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + }, + { + "name": "_publicKeys", + "type": "bytes" + }, + { + "name": "_signatures", + "type": "bytes" + } + ], + "name": "addSigningKeys", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getType", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_script", + "type": "bytes" + } + ], + "name": "getEVMScriptExecutor", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "clearNodeOperatorPenalty", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getRecoveryVault", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_limit", + "type": "uint256" + } + ], + "name": "getNodeOperatorIds", + "outputs": [ + { + "name": "nodeOperatorIds", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_limit", + "type": "uint256" + } + ], + "name": "getSigningKeys", + "outputs": [ + { + "name": "pubkeys", + "type": "bytes" + }, + { + "name": "signatures", + "type": "bytes" + }, + { + "name": "used", + "type": "bool[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fromIndex", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + } + ], + "name": "removeSigningKeysOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getNodeOperatorIsActive", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_name", + "type": "string" + } + ], + "name": "setNodeOperatorName", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_totalRewardShares", + "type": "uint256" + } + ], + "name": "getRewardsDistribution", + "outputs": [ + { + "name": "recipients", + "type": "address[]" + }, + { + "name": "shares", + "type": "uint256[]" + }, + { + "name": "penalized", + "type": "bool[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_indexFrom", + "type": "uint256" + }, + { + "name": "_indexTo", + "type": "uint256" + } + ], + "name": "invalidateReadyToDepositKeysRange", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_locator", + "type": "address" + }, + { + "name": "_type", + "type": "bytes32" + }, + { + "name": "_stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_delay", + "type": "uint256" + } + ], + "name": "setStuckPenaltyDelay", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "finalizeUpgrade_v3", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getStuckPenaltyDelay", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "removeSigningKey", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getRewardDistributionState", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fromIndex", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + } + ], + "name": "removeSigningKeys", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "isOperatorPenalized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "deactivateNodeOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "token", + "type": "address" + } + ], + "name": "allowRecoverability", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "STAKING_ROUTER_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + }, + { + "name": "_publicKeys", + "type": "bytes" + }, + { + "name": "_signatures", + "type": "bytes" + } + ], + "name": "addSigningKeysOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "appId", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getActiveNodeOperatorsCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "_rewardAddress", + "type": "address" + } + ], + "name": "addNodeOperator", + "outputs": [ + { + "name": "id", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getInitializationBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getUnusedSigningKeyCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "onRewardsMinted", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MANAGE_NODE_OPERATOR_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "distributeReward", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "onWithdrawalCredentialsChanged", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "activateNodeOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_rewardAddress", + "type": "address" + } + ], + "name": "setNodeOperatorRewardAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fullInfo", + "type": "bool" + } + ], + "name": "getNodeOperator", + "outputs": [ + { + "name": "active", + "type": "bool" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "rewardAddress", + "type": "address" + }, + { + "name": "totalVettedValidators", + "type": "uint64" + }, + { + "name": "totalExitedValidators", + "type": "uint64" + }, + { + "name": "totalAddedValidators", + "type": "uint64" + }, + { + "name": "totalDepositedValidators", + "type": "uint64" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_locator", + "type": "address" + }, + { + "name": "_type", + "type": "bytes32" + }, + { + "name": "_stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "finalizeUpgrade_v2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getStakingModuleSummary", + "outputs": [ + { + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_exitedValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateExitedValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_stuckValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateStuckValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + } + ], + "name": "transferToVault", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_sender", + "type": "address" + }, + { + "name": "_role", + "type": "bytes32" + }, + { + "name": "_params", + "type": "uint256[]" + } + ], + "name": "canPerform", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_refundedValidatorsCount", + "type": "uint256" + } + ], + "name": "updateRefundedValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getEVMScriptRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getNodeOperatorsCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_vettedSigningKeysCount", + "type": "uint64" + } + ], + "name": "setNodeOperatorStakingLimit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getNodeOperatorSummary", + "outputs": [ + { + "name": "targetLimitMode", + "type": "uint256" + }, + { + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "getSigningKey", + "outputs": [ + { + "name": "key", + "type": "bytes" + }, + { + "name": "depositSignature", + "type": "bytes" + }, + { + "name": "used", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_NODE_OPERATOR_NAME_LENGTH", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_vettedSigningKeysCounts", + "type": "bytes" + } + ], + "name": "decreaseVettedSigningKeysCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_depositsCount", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "obtainDepositData", + "outputs": [ + { + "name": "publicKeys", + "type": "bytes" + }, + { + "name": "signatures", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getKeysOpIndex", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kernel", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getLocator", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "SET_NODE_OPERATOR_LIMIT_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getTotalSigningKeyCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isPetrified", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_STUCK_PENALTY_DELAY", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "onExitedAndStuckValidatorsCountsUpdated", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_NODE_OPERATORS_COUNT", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "removeSigningKeyOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_exitedValidatorsCount", + "type": "uint256" + }, + { + "name": "_stuckValidatorsCount", + "type": "uint256" + } + ], + "name": "unsafeUpdateValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MANAGE_SIGNING_KEYS", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "isOperatorPenaltyCleared", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "name", + "type": "string" + }, + { + "indexed": false, + "name": "rewardAddress", + "type": "address" + }, + { + "indexed": false, + "name": "stakingLimit", + "type": "uint64" + } + ], + "name": "NodeOperatorAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "active", + "type": "bool" + } + ], + "name": "NodeOperatorActiveSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "name", + "type": "string" + } + ], + "name": "NodeOperatorNameSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "rewardAddress", + "type": "address" + } + ], + "name": "NodeOperatorRewardAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalKeysTrimmed", + "type": "uint64" + } + ], + "name": "NodeOperatorTotalKeysTrimmed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "keysOpIndex", + "type": "uint256" + } + ], + "name": "KeysOpIndexSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "moduleType", + "type": "bytes32" + } + ], + "name": "StakingModuleTypeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "rewardAddress", + "type": "address" + }, + { + "indexed": false, + "name": "sharesAmount", + "type": "uint256" + } + ], + "name": "RewardsDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "state", + "type": "uint8" + } + ], + "name": "RewardDistributionStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "locatorAddress", + "type": "address" + } + ], + "name": "LocatorContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "approvedValidatorsCount", + "type": "uint256" + } + ], + "name": "VettedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "depositedValidatorsCount", + "type": "uint256" + } + ], + "name": "DepositedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "exitedValidatorsCount", + "type": "uint256" + } + ], + "name": "ExitedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalValidatorsCount", + "type": "uint256" + } + ], + "name": "TotalSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "nonce", + "type": "uint256" + } + ], + "name": "NonceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "StuckPenaltyDelayChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + } + ], + "name": "StuckPenaltyStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "targetLimitMode", + "type": "uint256" + } + ], + "name": "TargetValidatorsCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "recipientAddress", + "type": "address" + }, + { + "indexed": false, + "name": "sharesPenalizedAmount", + "type": "uint256" + } + ], + "name": "NodeOperatorPenalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "version", + "type": "uint256" + } + ], + "name": "ContractVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "executor", + "type": "address" + }, + { + "indexed": false, + "name": "script", + "type": "bytes" + }, + { + "indexed": false, + "name": "input", + "type": "bytes" + }, + { + "indexed": false, + "name": "returnData", + "type": "bytes" + } + ], + "name": "ScriptResult", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "vault", + "type": "address" + }, + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "RecoverToVault", + "type": "event" + } +] diff --git a/tests/test_vote_sr_v2_mainnet.py b/tests/test_vote_sr_v2_mainnet.py new file mode 100644 index 000000000..d5a35776f --- /dev/null +++ b/tests/test_vote_sr_v2_mainnet.py @@ -0,0 +1,464 @@ +import pytest + +from utils.config import ( + contracts, + STAKING_ROUTER_IMPL, + LIDO_LOCATOR_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, + NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + SIMPLE_DVT_ARAGON_APP_ID, + SIMPLE_DVT_IMPL, + ACCOUNTING_ORACLE_IMPL, +) +from scripts.vote_sr_v2_mainnet import start_vote +from utils.config import ( + contracts, + LDO_HOLDER_ADDRESS_FOR_TESTS, +) +from brownie import interface, Contract +from utils.test.tx_tracing_helpers import * +from utils.test.event_validators.permission import validate_grant_role_event, validate_revoke_role_event +from utils.test.event_validators.common import validate_events_chain +from utils.test.event_validators.repo_upgrade import validate_repo_upgrade_event, RepoUpgrade +from utils.test.event_validators.aragon import validate_app_update_event +from typing import NamedTuple + + +class StakingModuleItem(NamedTuple): + id: int + staking_module_fee: int + stake_share_limit: int + treasury_fee: int + priority_exit_share_threshold: int + max_deposits_per_block: int + min_deposit_block_distance: int + + +STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" +PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" +STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" +MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" +OLD_LOCATOR_IMPL_ADDRESS = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" +OLD_SR_IMPL_ADDRESS = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" +OLD_NOR_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" +OLD_SDVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" +OLD_ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" +CURATED_MODULE_ID = 1 +SIMPLE_DVT_MODULE_ID = 2 +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 + +SR_VERSION = 2 +NOR_VERSION = 3 +DISTRIBUTED = 2 +SDVT_VERSION = 3 +AO_VERSION = 2 + +# new added fields +CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 +CURATED_MAX_DEPOSITS_PER_BLOCK = 50 +CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 +SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 +SDVT_MAX_DEPOSITS_PER_BLOCK = 50 +SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 + +nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" +sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" + +CURATED_MODULE_BEFORE_VOTE = { + "id": 1, + "name": "curated-onchain-v1", + "stakingModuleFee": 500, + "treasuryFee": 500, + "targetShare": 10000, + "priorityExitShareThreshold": None, + "maxDepositsPerBlock": None, + "minDepositBlockDistance": None, +} + +SDVT_MODULE_BEFORE_VOTE = { + "id": 2, + "name": "SimpleDVT", + "stakingModuleAddress": "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "stakingModuleFee": 800, + "treasuryFee": 200, + "targetShare": 50, + "priorityExitShareThreshold": None, + "maxDepositsPerBlock": None, + "minDepositBlockDistance": None, +} + +CURATED_MODULE_AFTER_VOTE = CURATED_MODULE_BEFORE_VOTE.copy() +CURATED_MODULE_AFTER_VOTE.update( + { + "priorityExitShareThreshold": CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, + "maxDepositsPerBlock": CURATED_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, + } +) + +SDVT_MODULE_AFTER_VOTE = SDVT_MODULE_BEFORE_VOTE.copy() +SDVT_MODULE_AFTER_VOTE.update( + { + "priorityExitShareThreshold": SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS, + "maxDepositsPerBlock": SDVT_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": SDVT_MIN_DEPOSIT_BLOCK_DISTANCES, + } +) + +OLD_SR_ABI = bi = [ + { + "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], + "name": "getStakingModule", + "outputs": [ + { + "components": [ + {"internalType": "uint24", "name": "id", "type": "uint24"}, + {"internalType": "address", "name": "stakingModuleAddress", "type": "address"}, + {"internalType": "uint16", "name": "stakingModuleFee", "type": "uint16"}, + {"internalType": "uint16", "name": "treasuryFee", "type": "uint16"}, + {"internalType": "uint16", "name": "stakeShareLimit", "type": "uint16"}, + {"internalType": "uint8", "name": "status", "type": "uint8"}, + {"internalType": "string", "name": "name", "type": "string"}, + {"internalType": "uint64", "name": "lastDepositAt", "type": "uint64"}, + {"internalType": "uint256", "name": "lastDepositBlock", "type": "uint256"}, + {"internalType": "uint256", "name": "exitedValidatorsCount", "type": "uint256"}, + ], + "internalType": "struct StakingRouter.StakingModule", + "name": "", + "type": "tuple", + } + ], + "stateMutability": "view", + "type": "function", + } +] + + +def test_vote( + helpers, + accounts, + vote_ids_from_env, +): + staking_router = contracts.staking_router + + sr_proxy = interface.OssifiableProxy(contracts.staking_router) + locator_proxy = interface.OssifiableProxy(contracts.lido_locator) + nor_proxy = interface.AppProxyUpgradeable(contracts.node_operators_registry) + sdvt_proxy = interface.AppProxyUpgradeable(contracts.simple_dvt) + ao_proxy = interface.OssifiableProxy(contracts.accounting_oracle) + vebo_proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) + + assert staking_router.getStakingModulesCount() == 2 + + # Before voting tests + # locator + check_ossifiable_proxy_impl(locator_proxy, OLD_LOCATOR_IMPL_ADDRESS) + # DSM + check_dsm_roles_before_vote() + # SR + check_ossifiable_proxy_impl(sr_proxy, OLD_SR_IMPL_ADDRESS) + check_module_before_vote(CURATED_MODULE_BEFORE_VOTE) + check_module_before_vote(SDVT_MODULE_BEFORE_VOTE) + # NOR + nor_old_app = contracts.nor_app_repo.getLatest() + assert nor_proxy.implementation() == OLD_NOR_IMPL + assert_repo_before_vote(nor_old_app, 4, OLD_NOR_IMPL, nor_uri) + # SDVT + sdvt_old_app = contracts.simple_dvt_app_repo.getLatest() + assert sdvt_proxy.implementation() == OLD_SDVT_IMPL + assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, sdvt_uri) + # AO + check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) + # no prermission to manage consensus version on agent + check_manage_consensus_role() + + # VEBO consensus version + assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 + + # START VOTE + if len(vote_ids_from_env) > 0: + (vote_id,) = vote_ids_from_env + else: + tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS} + vote_id, _ = start_vote(tx_params, silent=True) + + vote_tx = helpers.execute_vote(accounts, vote_id, contracts.voting) + + print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") + + # locator + check_ossifiable_proxy_impl(locator_proxy, LIDO_LOCATOR_IMPL) + # DSM + check_dsm_roles_after_vote() + # SR + check_ossifiable_proxy_impl(sr_proxy, STAKING_ROUTER_IMPL) + check_module_after_vote(CURATED_MODULE_AFTER_VOTE) + check_module_after_vote(SDVT_MODULE_AFTER_VOTE) + # AO + check_ossifiable_proxy_impl(ao_proxy, ACCOUNTING_ORACLE_IMPL) + + # no prermission to manage consensus version on agent + check_manage_consensus_role() + # VEBO consensus version + assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION + + # Events check + events = group_voting_events(vote_tx) + + assert len(events) == 17 + + validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) + validate_dsm_roles_events(events) + validate_upgrade_events(events[4], STAKING_ROUTER_IMPL) + + validate_staking_module_update( + events[5], + [ + StakingModuleItem( + CURATED_MODULE_AFTER_VOTE["id"], + CURATED_MODULE_AFTER_VOTE["stakingModuleFee"], + CURATED_MODULE_AFTER_VOTE["targetShare"], + CURATED_MODULE_AFTER_VOTE["treasuryFee"], + CURATED_MODULE_AFTER_VOTE["priorityExitShareThreshold"], + CURATED_MODULE_AFTER_VOTE["maxDepositsPerBlock"], + CURATED_MODULE_AFTER_VOTE["minDepositBlockDistance"], + ), + StakingModuleItem( + SDVT_MODULE_AFTER_VOTE["id"], + SDVT_MODULE_AFTER_VOTE["stakingModuleFee"], + SDVT_MODULE_AFTER_VOTE["targetShare"], + SDVT_MODULE_AFTER_VOTE["treasuryFee"], + SDVT_MODULE_AFTER_VOTE["priorityExitShareThreshold"], + SDVT_MODULE_AFTER_VOTE["maxDepositsPerBlock"], + SDVT_MODULE_AFTER_VOTE["minDepositBlockDistance"], + ), + ], + ) + + nor_new_app = contracts.nor_app_repo.getLatest() + assert_repo_update(nor_new_app, nor_old_app, NODE_OPERATORS_REGISTRY_IMPL, nor_uri) + validate_repo_upgrade_event(events[6], RepoUpgrade(6, nor_new_app[0])) + validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL) + validate_nor_update(events[8], NOR_VERSION) + + sdvt_new_app = contracts.simple_dvt_app_repo.getLatest() + assert_repo_update(sdvt_new_app, sdvt_old_app, SIMPLE_DVT_IMPL, sdvt_uri) + validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) + validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL) + validate_nor_update(events[11], SDVT_VERSION) + + # AO + validate_upgrade_events(events[12], ACCOUNTING_ORACLE_IMPL) + validate_ao_update(events[13], AO_VERSION, AO_CONSENSUS_VERSION) + + validate_grant_role_event( + events[14], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + ) + + validate_vebo_consensus_version_set(events[15]) + + validate_revoke_role_event( + events[16], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + ) + + +def check_ossifiable_proxy_impl(proxy, expected_impl): + current_impl_address = proxy.proxy__getImplementation() + assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" + + +def check_dsm_roles_before_vote(): + new_dsm_doesnt_have_unvet_role = contracts.staking_router.hasRole( + STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module + ) + assert not new_dsm_doesnt_have_unvet_role + + old_dsm_has_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) + + assert old_dsm_has_pause_role + + old_dsm_has_resume_role = contracts.staking_router.hasRole( + STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 + ) + + assert old_dsm_has_resume_role + + +def check_dsm_roles_after_vote(): + new_dsm_has_unvet_role = contracts.staking_router.hasRole( + STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module + ) + assert new_dsm_has_unvet_role + + old_dsm_doesnt_have_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) + assert not old_dsm_doesnt_have_pause_role + + old_dsm_doesnt_have_resume_role = contracts.staking_router.hasRole( + STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 + ) + assert not old_dsm_doesnt_have_resume_role + + +def check_manage_consensus_role(): + agent_has_manage_consensus_role = contracts.validators_exit_bus_oracle.hasRole( + MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address + ) + assert not agent_has_manage_consensus_role + + +def check_module_before_vote(expected_module_data: Dict): + sr_contract = Contract.from_abi("StakingContract", contracts.staking_router.address, OLD_SR_ABI) + module = sr_contract.getStakingModule(expected_module_data["id"]) + assert module["id"] == expected_module_data["id"] + assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] + assert module["treasuryFee"] == expected_module_data["treasuryFee"] + assert module["stakeShareLimit"] == expected_module_data["targetShare"] + assert "priorityExitShareThreshold" not in module + assert "maxDepositsPerBlock" not in module + assert "minDepositBlockDistance" not in module + + +def check_module_after_vote(expected_module_data: Dict): + module = contracts.staking_router.getStakingModule(expected_module_data["id"]) + assert module["id"] == expected_module_data["id"] + assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] + assert module["treasuryFee"] == expected_module_data["treasuryFee"] + assert module["stakeShareLimit"] == expected_module_data["targetShare"] + assert module["priorityExitShareThreshold"] == expected_module_data["priorityExitShareThreshold"] + assert module["maxDepositsPerBlock"] == expected_module_data["maxDepositsPerBlock"] + assert module["minDepositBlockDistance"] == expected_module_data["minDepositBlockDistance"] + + +def assert_repo_before_vote(old_app, version, contract_address, old_content_uri): + assert old_app[0][0] == version + assert old_app[2] == old_content_uri, "Content uri before vote is wrong" + assert old_app[1] == contract_address, "New address should match" + + +def assert_repo_update(new_app, old_app, contract_address, old_content_uri): + assert old_app[1] != new_app[1], "Address should change" + assert new_app[1] == contract_address, "New address should match" + assert new_app[0][0] == old_app[0][0] + 1, "Major version should increment" + assert old_app[2] == new_app[2], "Content uri should not be changed" + assert new_app[2] == old_content_uri, "Content uri should match" + + +# Events check + + +def validate_upgrade_events(events: EventDict, implementation: str): + _events_chain = ["LogScriptCall", "LogScriptCall", "Upgraded", "ScriptResult"] + validate_events_chain([e.name for e in events], _events_chain) + assert events.count("Upgraded") == 1 + assert events["Upgraded"]["implementation"] == implementation, "Wrong withdrawal vault proxy implementation" + + +def validate_dsm_roles_events(events: EventDict): + validate_revoke_role_event( + events[1], PAUSE_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address + ) + validate_revoke_role_event( + events[2], STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address + ) + + validate_grant_role_event( + events[3], STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module.address, contracts.agent.address + ) + + +def validate_staking_module_update(event: EventDict, module_items: List[StakingModuleItem]): + assert len(module_items) == 2 + + _events_chain = [ + "LogScriptCall", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ContractVersionSet", + ] + + validate_events_chain([e.name for e in event], _events_chain) + + assert event.count("StakingModuleFeesSet") == 2 + assert event.count("StakingModuleShareLimitSet") == 2 + assert event.count("StakingModuleMinDepositBlockDistanceSet") == 2 + assert event.count("StakingModuleMaxDepositsPerBlockSet") == 2 + assert event.count("ContractVersionSet") == 1 + + # curated + assert event["StakingModuleShareLimitSet"][0]["stakingModuleId"] == module_items[0].id + assert event["StakingModuleShareLimitSet"][0]["stakeShareLimit"] == module_items[0].stake_share_limit + assert ( + event["StakingModuleShareLimitSet"][0]["priorityExitShareThreshold"] + == module_items[0].priority_exit_share_threshold + ) + assert event["StakingModuleFeesSet"][0]["stakingModuleId"] == module_items[0].id + assert event["StakingModuleFeesSet"][0]["stakingModuleFee"] == module_items[0].staking_module_fee + assert event["StakingModuleFeesSet"][0]["treasuryFee"] == module_items[0].treasury_fee + + assert ( + event["StakingModuleMaxDepositsPerBlockSet"][0]["maxDepositsPerBlock"] == module_items[0].max_deposits_per_block + ) + + assert ( + event["StakingModuleMinDepositBlockDistanceSet"][0]["minDepositBlockDistance"] + == module_items[0].min_deposit_block_distance + ) + + assert event["ContractVersionSet"]["version"] == SR_VERSION + + assert event["StakingModuleShareLimitSet"][1]["stakingModuleId"] == module_items[1].id + assert event["StakingModuleShareLimitSet"][1]["stakeShareLimit"] == module_items[1].stake_share_limit + assert ( + event["StakingModuleShareLimitSet"][1]["priorityExitShareThreshold"] + == module_items[1].priority_exit_share_threshold + ) + assert event["StakingModuleFeesSet"][1]["stakingModuleId"] == module_items[1].id + assert event["StakingModuleFeesSet"][1]["stakingModuleFee"] == module_items[1].staking_module_fee + assert event["StakingModuleFeesSet"][1]["treasuryFee"] == module_items[1].treasury_fee + + assert ( + event["StakingModuleMaxDepositsPerBlockSet"][1]["maxDepositsPerBlock"] == module_items[1].max_deposits_per_block + ) + + assert ( + event["StakingModuleMinDepositBlockDistanceSet"][1]["minDepositBlockDistance"] + == module_items[1].min_deposit_block_distance + ) + + +def validate_nor_update(event: EventDict, version): + _events_chain = [ + "LogScriptCall", + "ContractVersionSet", + "RewardDistributionStateChanged", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["ContractVersionSet"]["version"] == version + assert event["RewardDistributionStateChanged"]["state"] == DISTRIBUTED + + +def validate_ao_update(event: EventDict, version, ao_consensus_version): + _events_chain = [ + "LogScriptCall", + "ContractVersionSet", + "ConsensusVersionSet", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["ContractVersionSet"]["version"] == version + assert event["ConsensusVersionSet"]["version"] == ao_consensus_version + assert event["ConsensusVersionSet"]["prevVersion"] == ao_consensus_version - 1 + + +def validate_vebo_consensus_version_set(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "ConsensusVersionSet", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event["ConsensusVersionSet"]["version"] == VEBO_CONSENSUS_VERSION From 8eab0f57f3c9e4d614bddcfbdeb5fc4c0e12697e Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 25 Jun 2024 16:56:37 +0200 Subject: [PATCH 024/220] test: fix sanity checker parameters --- utils/test/oracle_report_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index 39a8a1b1d..72cf670a6 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -118,7 +118,7 @@ def encode_data_from_abi(data, abi, func_name): def get_finalization_batches( share_rate: int, limited_withdrawal_vault_balance, limited_el_rewards_vault_balance ) -> list[int]: - (_, _, _, _, _, _, _, requestTimestampMargin, _) = contracts.oracle_report_sanity_checker.getOracleReportLimits() + (_, _, _, _, _, _, _, requestTimestampMargin, _, _) = contracts.oracle_report_sanity_checker.getOracleReportLimits() buffered_ether = contracts.lido.getBufferedEther() unfinalized_steth = contracts.withdrawal_queue.unfinalizedStETH() reserved_buffer = min(buffered_ether, unfinalized_steth) From 09ac11eb96827bd5fe532e9c34eedd6864bf5bff Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 25 Jun 2024 17:52:08 +0200 Subject: [PATCH 025/220] test: fix test_permissions --- tests/regression/test_permissions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/regression/test_permissions.py b/tests/regression/test_permissions.py index d3a297737..019686d14 100644 --- a/tests/regression/test_permissions.py +++ b/tests/regression/test_permissions.py @@ -73,8 +73,7 @@ def protocol_permissions(): "roles": { "DEFAULT_ADMIN_ROLE": [contracts.agent], "MANAGE_WITHDRAWAL_CREDENTIALS_ROLE": [], - "STAKING_MODULE_PAUSE_ROLE": [contracts.deposit_security_module], - "STAKING_MODULE_RESUME_ROLE": [contracts.deposit_security_module], + "STAKING_MODULE_UNVETTING_ROLE": [contracts.deposit_security_module], "STAKING_MODULE_MANAGE_ROLE": [contracts.agent], "REPORT_EXITED_VALIDATORS_ROLE": [contracts.accounting_oracle], "UNSAFE_SET_EXITED_VALIDATORS_ROLE": [], @@ -161,7 +160,8 @@ def protocol_permissions(): "roles": { "DEFAULT_ADMIN_ROLE": [contracts.agent], "ALL_LIMITS_MANAGER_ROLE": [], - "CHURN_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE": [], + "EXITED_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE": [], + "APPEARED_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE": [], "ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE": [], "ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE": [], "SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE": [], From facea1696f5e41edc4953afeab602820cf1346cf Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Wed, 26 Jun 2024 00:36:28 +0400 Subject: [PATCH 026/220] fix: submit correct part of voting script --- scripts/holesky/vote_sr_v2_holesky.py | 386 ++++++++++++++++++++++++++ tests/regression/test_permissions.py | 5 +- 2 files changed, 389 insertions(+), 2 deletions(-) create mode 100644 scripts/holesky/vote_sr_v2_holesky.py diff --git a/scripts/holesky/vote_sr_v2_holesky.py b/scripts/holesky/vote_sr_v2_holesky.py new file mode 100644 index 000000000..e28973a3a --- /dev/null +++ b/scripts/holesky/vote_sr_v2_holesky.py @@ -0,0 +1,386 @@ +""" +SR V2 +1. Update locator implementation +2. Revoke pause role from old DSM +3. Revoke resume role from old DSM +4. Grant unvetting role to new DSM +5. Update SR implementation +6. Call finalize upgrade on SR +7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo +8. Update `NodeOperatorsRegistry` implementation +9. Finalize NOR upgrade +10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo +11. Update `SimpleDVT` implementation +12. Finalize SimpleDVT upgrade +13. Publish new `Sandbox` implementation in Sandbox app APM repo +14. Update `Sandbox` implementation +15. Finalize Sandbox upgrade +16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, +17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +18. Grant manage consensus role to agent ${AGENT}` +19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +20. Revoke manage consensus role from agent ${AGENT}" + +CSM + +21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE +22. Add staking module +23. Grant request burn role to CSAccounting contract +24. Grant resume role to agent +25. Resume staking module +26. Revoke resume role from agent +27. Update initial epoch +28. Add CS settle EL stealing factory to ET +29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} +""" + +import time + +try: + from brownie import interface, accounts +except ImportError: + print("You're probably running inside Brownie console. Please call:") + print("set_console_globals(interface=interface)") + + +from typing import Dict, Tuple, Optional +from utils.config import ( + get_deployer_account, + get_is_live, + contracts, + NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + SIMPLE_DVT_ARAGON_APP_ID, + SANDBOX_APP_ID, + LIDO_LOCATOR_IMPL, + STAKING_ROUTER_IMPL, + ACCOUNTING_ORACLE_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, + CS_ACCOUNTING_ADDRESS, + AGENT, + CS_ORACLE_HASH_CONSENSUS_ADDRESS, +) + +from utils.repo import ( + add_implementation_to_nor_app_repo, + add_implementation_to_sdvt_app_repo, + add_implementation_to_sandbox_app_repo, +) + +from utils.kernel import update_app_implementation + +from utils.voting import bake_vote_items, confirm_vote_script, create_vote + +from brownie.network.transaction import TransactionReceipt +from utils.agent import agent_forward + +# SR +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] +MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] +MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] +NOR_VERSION = ["2", "0", "0"] +SDVT_VERSION = ["2", "0", "0"] +SANDBOX_VERSION = ["2", "0", "0"] +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 + +# CSM + +CS_MODULE_NAME = "CommunityStaking" +CS_STAKE_SHARE_LIMIT = 2000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 +CS_STAKING_MODULE_FEE = 800 +CS_TREASURY_FEE = 200 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 58050 + + +def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.lido_locator) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_staking_router_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.staking_router) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_staking_router_finalize() -> Tuple[str, str]: + proxy = interface.StakingRouter(contracts.staking_router) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input( + PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES + ) + + +def encode_nor_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.node_operators_registry) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_sdvt_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.simple_dvt) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_sandbox_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.sandbox) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.accounting_oracle) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_ao_finalize() -> Tuple[str, str]: + proxy = interface.AccountingOracle(contracts.accounting_oracle) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) + + +def encode_set_consensus_version() -> Tuple[str, str]: + proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) + return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) + + +def get_repo_uri(repo_address: str) -> str: + contract = interface.Repo(repo_address).getLatest() + return contract["contentURI"] + + +def get_repo_version(repo_address: str) -> tuple[int, int, int]: + contract = interface.Repo(repo_address).getLatest() + return contract["semanticVersion"] + + +def grantCsmResumeRoleToAgent() -> Tuple[str, str]: + + return ( + contracts.csm.address, + contracts.csm.grantRole.encode_input( + # keccak256 RESUME_ROLE + "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7", + contracts.agent.address, + ), + ) + + +def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: + """Prepare and run voting.""" + + nor_repo = contracts.nor_app_repo.address + simple_dvt_repo = contracts.simple_dvt_app_repo.address + sandbox_repo = contracts.sandbox_repo.address + + nor_uri = get_repo_uri(nor_repo) + simple_dvt_uri = get_repo_uri(simple_dvt_repo) + sandbox_uri = get_repo_uri(sandbox_repo) + + call_script_items = [ + # SR 2 + # 1) + agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), + # 2) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.revokeRole.encode_input( + # keccak256 STAKING_MODULE_PAUSE_ROLE + "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", + contracts.deposit_security_module_v2, + ), + ) + ] + ), + # 3) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.revokeRole.encode_input( + # keccak256 STAKING_MODULE_RESUME_ROLE + "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", + contracts.deposit_security_module_v2, + ), + ) + ] + ), + # 4) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.grantRole.encode_input( + # keccak256 STAKING_MODULE_UNVETTING_ROLE + "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", + contracts.deposit_security_module, + ), + ) + ] + ), + # 5) + agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), + # 6) + encode_staking_router_finalize(), + # 7) + add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), + # 8) + update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # 9) + encode_nor_finalize(), + # 10) + add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), + # 11) + update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # 12) + encode_sdvt_finalize(), + # 13) + add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), + # 14) + update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + # 15) + encode_sandbox_finalize(), + # 16) + agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + # 17) + encode_ao_finalize(), + # 18) + agent_forward( + [ + ( + contracts.validators_exit_bus_oracle.address, + contracts.validators_exit_bus_oracle.grantRole.encode_input( + # keccak256 MANAGE_CONSENSUS_VERSION_ROLE + "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", + contracts.agent.address, + ), + ) + ] + ), + # 19) + agent_forward([encode_set_consensus_version()]), + # 20) + agent_forward( + [ + ( + contracts.validators_exit_bus_oracle.address, + contracts.validators_exit_bus_oracle.revokeRole.encode_input( + # keccak256 MANAGE_CONSENSUS_VERSION_ROLE + "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", + contracts.agent.address, + ), + ) + ] + ), + # CSM + # 21) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.grantRole.encode_input( + # STAKING_MODULE_MANAGE_ROLE + "0x3105bcbf19d4417b73ae0e58d508a65ecf75665e46c2622d8521732de6080c48", + contracts.agent.address, + ), + ) + ] + ), + # 22) + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.addStakingModule.encode_input( + CS_MODULE_NAME, + contracts.csm.address, + CS_STAKE_SHARE_LIMIT, + CS_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_STAKING_MODULE_FEE, + CS_TREASURY_FEE, + CS_MAX_DEPOSITS_PER_BLOCK, + CS_MIN_DEPOSIT_BLOCK_DISTANCE, + ), + ), + ] + ), + # 23) + agent_forward( + [ + ( + contracts.burner.address, + contracts.burner.grantRole.encode_input( + # keccak256 'REQUEST_BURN_SHARES_ROLE' + "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8", + CS_ACCOUNTING_ADDRESS, + ), + ) + ] + ), + # 24) + # agent_forward([grantCsmResumeRoleToAgent()]), + # # 25) + # agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), + # # 26) + # ( + # contracts.csm.address, + # contracts.csm.revokeRole.encode_input( + # "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7", contracts.agent.address + # ), + # ), + # # 27) + # (contracts.csmHashConsensus.address, contracts.csmHashConsensus.updateInitialEpoch(CS_ORACLE_INITIAL_EPOCH)), + # 28) + ] + + vote_desc_items = [ + "1. Update locator implementation", + "2. Revoke pause role from old DSM", + "3. Revoke resume role from old DSM", + "4. Grant unvetting role to new DSM", + "5. Update SR implementation", + "6. Call finalize upgrade on SR", + "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + "8. Update `NodeOperatorsRegistry` implementation", + "9. Finalize NOR upgrade", + "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", + "11. Update `SimpleDVT` implementation", + "12. Finalize SimpleDVT upgrade", + "13. Publish new `Sandbox` implementation in Sandbox app APM repo", + "14. Update `Sandbox` implementation", + "15. Finalize Sandbox upgrade", + "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + "18. Grant manage consensus role to agent ${AGENT}", + "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + "20. Revoke manage consensus role from agent ${AGENT}", + "21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE", + "22. Add staking module", + "23. Grant request burn role to CSAccounting contract", + # "24. Grant resume role to agent", + # "25. Resume staking module", + # "26. Revoke resume role from agent", + # "27. Update initial epoch", + # 28. Add CS settle EL stealing factory to ET + # 29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} + ] + + vote_items = bake_vote_items(vote_desc_items, call_script_items) + + return confirm_vote_script(vote_items, silent) and list(create_vote(vote_items, tx_params)) + + +def main(): + tx_params = {"from": get_deployer_account()} + + if get_is_live(): + tx_params["max_fee"] = "300 gwei" + tx_params["priority_fee"] = "2 gwei" + + print(tx_params) + + vote_id, _ = start_vote(tx_params=tx_params, silent=False) + + vote_id >= 0 and print(f"Vote created: {vote_id}.") + + time.sleep(10) # hack for waiting thread #2. diff --git a/tests/regression/test_permissions.py b/tests/regression/test_permissions.py index d3a297737..452d246d9 100644 --- a/tests/regression/test_permissions.py +++ b/tests/regression/test_permissions.py @@ -73,8 +73,9 @@ def protocol_permissions(): "roles": { "DEFAULT_ADMIN_ROLE": [contracts.agent], "MANAGE_WITHDRAWAL_CREDENTIALS_ROLE": [], - "STAKING_MODULE_PAUSE_ROLE": [contracts.deposit_security_module], - "STAKING_MODULE_RESUME_ROLE": [contracts.deposit_security_module], + # "STAKING_MODULE_PAUSE_ROLE": [contracts.deposit_security_module], + # "STAKING_MODULE_RESUME_ROLE": [contracts.deposit_security_module], + "STAKING_MODULE_UNVETTING_ROLE": [contracts.deposit_security_module], "STAKING_MODULE_MANAGE_ROLE": [contracts.agent], "REPORT_EXITED_VALIDATORS_ROLE": [contracts.accounting_oracle], "UNSAFE_SET_EXITED_VALIDATORS_ROLE": [], From 9bc7dda110d67604074078282d6d737c6bc0702f Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Wed, 26 Jun 2024 00:39:07 +0400 Subject: [PATCH 027/220] fix: removed duplicated script --- scripts/vote_sr_v2_holesky.py | 386 ---------------------------------- 1 file changed, 386 deletions(-) delete mode 100644 scripts/vote_sr_v2_holesky.py diff --git a/scripts/vote_sr_v2_holesky.py b/scripts/vote_sr_v2_holesky.py deleted file mode 100644 index 01109352e..000000000 --- a/scripts/vote_sr_v2_holesky.py +++ /dev/null @@ -1,386 +0,0 @@ -""" -SR V2 -1. Update locator implementation -2. Revoke pause role from old DSM -3. Revoke resume role from old DSM -4. Grant unvetting role to new DSM -5. Update SR implementation -6. Call finalize upgrade on SR -7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo -8. Update `NodeOperatorsRegistry` implementation -9. Finalize NOR upgrade -10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo -11. Update `SimpleDVT` implementation -12. Finalize SimpleDVT upgrade -13. Publish new `Sandbox` implementation in Sandbox app APM repo -14. Update `Sandbox` implementation -15. Finalize Sandbox upgrade -16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, -17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, -18. Grant manage consensus role to agent ${AGENT}` -19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` -20. Revoke manage consensus role from agent ${AGENT}" - -CSM - -21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE -22. Add staking module -23. Grant request burn role to CSAccounting contract -24. Grant resume role to agent -25. Resume staking module -26. Revoke resume role from agent -27. Update initial epoch -28. Add CS settle EL stealing factory to ET -29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} -""" - -import time - -try: - from brownie import interface, accounts -except ImportError: - print("You're probably running inside Brownie console. Please call:") - print("set_console_globals(interface=interface)") - - -from typing import Dict, Tuple, Optional -from utils.config import ( - get_deployer_account, - get_is_live, - contracts, - NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, - SIMPLE_DVT_ARAGON_APP_ID, - SANDBOX_APP_ID, - LIDO_LOCATOR_IMPL, - STAKING_ROUTER_IMPL, - ACCOUNTING_ORACLE_IMPL, - NODE_OPERATORS_REGISTRY_IMPL, - CS_ACCOUNTING_ADDRESS, - AGENT, - CS_ORACLE_HASH_CONSENSUS_ADDRESS, -) - -from utils.repo import ( - add_implementation_to_nor_app_repo, - add_implementation_to_sdvt_app_repo, - add_implementation_to_sandbox_app_repo, -) - -from utils.kernel import update_app_implementation - -from utils.voting import bake_vote_items, confirm_vote_script, create_vote - -from brownie.network.transaction import TransactionReceipt -from utils.agent import agent_forward - -# SR -PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] -MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] -MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] -NOR_VERSION = ["2", "0", "0"] -SDVT_VERSION = ["2", "0", "0"] -SANDBOX_VERSION = ["2", "0", "0"] -AO_CONSENSUS_VERSION = 2 -VEBO_CONSENSUS_VERSION = 2 - -# CSM - -CS_MODULE_NAME = "CommunityStaking" -CS_STAKE_SHARE_LIMIT = 2000 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 -CS_STAKING_MODULE_FEE = 800 -CS_TREASURY_FEE = 200 -CS_MAX_DEPOSITS_PER_BLOCK = 30 -CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 58050 - - -def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.lido_locator) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_staking_router_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.staking_router) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_staking_router_finalize() -> Tuple[str, str]: - proxy = interface.StakingRouter(contracts.staking_router) - return proxy.address, proxy.finalizeUpgrade_v2.encode_input( - PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES - ) - - -def encode_nor_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.node_operators_registry) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_sdvt_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.simple_dvt) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_sandbox_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.sandbox) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.accounting_oracle) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_ao_finalize() -> Tuple[str, str]: - proxy = interface.AccountingOracle(contracts.accounting_oracle) - return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) - - -def encode_set_consensus_version() -> Tuple[str, str]: - proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) - return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) - - -def get_repo_uri(repo_address: str) -> str: - contract = interface.Repo(repo_address).getLatest() - return contract["contentURI"] - - -def get_repo_version(repo_address: str) -> tuple[int, int, int]: - contract = interface.Repo(repo_address).getLatest() - return contract["semanticVersion"] - - -def grantCsmResumeRoleToAgent() -> Tuple[str, str]: - - return ( - contracts.csm.address, - contracts.csm.grantRole.encode_input( - # keccak256 RESUME_ROLE - "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7", - contracts.agent.address, - ), - ) - - -def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: - """Prepare and run voting.""" - - nor_repo = contracts.nor_app_repo.address - simple_dvt_repo = contracts.simple_dvt_app_repo.address - sandbox_repo = contracts.sandbox_repo.address - - nor_uri = get_repo_uri(nor_repo) - simple_dvt_uri = get_repo_uri(simple_dvt_repo) - sandbox_uri = get_repo_uri(sandbox_repo) - - call_script_items = [ - # SR 2 - # 1) - # agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), - # # 2) - # agent_forward( - # [ - # ( - # contracts.staking_router.address, - # contracts.staking_router.revokeRole.encode_input( - # # keccak256 STAKING_MODULE_PAUSE_ROLE - # "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", - # contracts.deposit_security_module_v2, - # ), - # ) - # ] - # ), - # 3) - # agent_forward( - # [ - # ( - # contracts.staking_router.address, - # contracts.staking_router.revokeRole.encode_input( - # # keccak256 STAKING_MODULE_RESUME_ROLE - # "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", - # contracts.deposit_security_module_v2, - # ), - # ) - # ] - # ), - # # 4) - # agent_forward( - # [ - # ( - # contracts.staking_router.address, - # contracts.staking_router.grantRole.encode_input( - # # keccak256 STAKING_MODULE_UNVETTING_ROLE - # "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", - # contracts.deposit_security_module, - # ), - # ) - # ] - # ), - # 5) - # agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), - # # 6) - # encode_staking_router_finalize(), - # # 7) - # add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), - # # 8) - # update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # # 9) - # encode_nor_finalize(), - # # 10) - # add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), - # # 11) - # update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # # 12) - # encode_sdvt_finalize(), - # # 13) - # add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), - # # 14) - # update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # # 15) - # encode_sandbox_finalize(), - # # 16) - # agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), - # # 17) - # encode_ao_finalize(), - # 18) - # agent_forward( - # [ - # ( - # contracts.validators_exit_bus_oracle.address, - # contracts.validators_exit_bus_oracle.grantRole.encode_input( - # # keccak256 MANAGE_CONSENSUS_VERSION_ROLE - # "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", - # contracts.agent.address, - # ), - # ) - # ] - # ), - # # 19) - # agent_forward([encode_set_consensus_version()]), - # # 20) - # agent_forward( - # [ - # ( - # contracts.validators_exit_bus_oracle.address, - # contracts.validators_exit_bus_oracle.revokeRole.encode_input( - # # keccak256 MANAGE_CONSENSUS_VERSION_ROLE - # "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", - # contracts.agent.address, - # ), - # ) - # ] - # ), - # CSM - # 21) - # agent_forward( - # [ - # ( - # contracts.staking_router.address, - # contracts.staking_router.grantRole.encode_input( - # # STAKING_MODULE_MANAGE_ROLE - # "0x3105bcbf19d4417b73ae0e58d508a65ecf75665e46c2622d8521732de6080c48", - # contracts.agent.address, - # ), - # ) - # ] - # ), - # 22) - # agent_forward( - # [ - # ( - # contracts.staking_router.address, - # contracts.staking_router.addStakingModule.encode_input( - # CS_MODULE_NAME, - # contracts.csm.address, - # CS_STAKE_SHARE_LIMIT, - # CS_PRIORITY_EXIT_SHARE_THRESHOLD, - # CS_STAKING_MODULE_FEE, - # CS_TREASURY_FEE, - # CS_MAX_DEPOSITS_PER_BLOCK, - # CS_MIN_DEPOSIT_BLOCK_DISTANCE, - # ), - # ), - # ] - # ), - # 23) - # agent_forward( - # [ - # ( - # contracts.burner.address, - # contracts.burner.grantRole.encode_input( - # # keccak256 'REQUEST_BURN_SHARES_ROLE' - # "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8", - # CS_ACCOUNTING_ADDRESS, - # ), - # ) - # ] - # ), - # 24) - agent_forward([grantCsmResumeRoleToAgent()]), - # # 25) - # agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), - # # 26) - # ( - # contracts.csm.address, - # contracts.csm.revokeRole.encode_input( - # "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7", contracts.agent.address - # ), - # ), - # # 27) - # (contracts.csmHashConsensus.address, contracts.csmHashConsensus.updateInitialEpoch(CS_ORACLE_INITIAL_EPOCH)), - # 28) - ] - - vote_desc_items = [ - # "1. Update locator implementation", - # "2. Revoke pause role from old DSM", - # "3. Revoke resume role from old DSM", - # "4. Grant unvetting role to new DSM", - # "5. Update SR implementation", - # "6. Call finalize upgrade on SR", - # "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", - # "8. Update `NodeOperatorsRegistry` implementation", - # "9. Finalize NOR upgrade", - # "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", - # "11. Update `SimpleDVT` implementation", - # "12. Finalize SimpleDVT upgrade", - # "13. Publish new `Sandbox` implementation in Sandbox app APM repo", - # "14. Update `Sandbox` implementation", - # "15. Finalize Sandbox upgrade", - # "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", - # "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - # "18. Grant manage consensus role to agent ${AGENT}", - # "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", - # "20. Revoke manage consensus role from agent ${AGENT}", - # "21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE", - # "22. Add staking module", - # "23. Grant request burn role to CSAccounting contract", - "24. Grant resume role to agent", - # "25. Resume staking module", - # "26. Revoke resume role from agent", - # "27. Update initial epoch", - # 28. Add CS settle EL stealing factory to ET - # 29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} - ] - - vote_items = bake_vote_items(vote_desc_items, call_script_items) - - return confirm_vote_script(vote_items, silent) and list(create_vote(vote_items, tx_params)) - - -def main(): - tx_params = {"from": get_deployer_account()} - - if get_is_live(): - tx_params["max_fee"] = "300 gwei" - tx_params["priority_fee"] = "2 gwei" - - print(tx_params) - - vote_id, _ = start_vote(tx_params=tx_params, silent=False) - - vote_id >= 0 and print(f"Vote created: {vote_id}.") - - time.sleep(10) # hack for waiting thread #2. From 72c5e5e5d919d65c60658965a07fb9768d621d23 Mon Sep 17 00:00:00 2001 From: KRogLA Date: Wed, 26 Jun 2024 02:48:51 +0500 Subject: [PATCH 028/220] fix: config for new forks --- brownie-config.yml | 4 ++ network-config.yaml | 163 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/brownie-config.yml b/brownie-config.yml index 3b8f441a1..98db6cfbe 100644 --- a/brownie-config.yml +++ b/brownie-config.yml @@ -4,6 +4,10 @@ dependencies: networks: default: mainnet-fork + development: + priority_fee: auto + live: + priority_fee: auto autofetch_sources: true diff --git a/network-config.yaml b/network-config.yaml index deca032b2..9073bb4a5 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -60,6 +60,7 @@ development: gas_limit: 30000000 mnemonic: brownie port: 8545 + evm_version: shanghai host: http://127.0.0.1 id: holesky-fork name: Ganache-CLI (Holesky Fork) @@ -93,3 +94,165 @@ development: timeout: 360 # https://github.com/mds1/multicall#multicall2-contract-addresses multicall2: "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696" + + + +development: + - name: Anvil + id: anvil + cmd: anvil + host: http://127.0.0.1 + cmd_settings: + port: 8545 + - name: Anvil (Mainnet Fork) + id: anvil-fork + cmd: anvil + host: http://127.0.0.1 + cmd_settings: + fork: mainnet + port: 8545 + - name: Anvil (Holesky Fork) + id: anvil-holesky-fork + cmd: anvil + host: http://127.0.0.1 + cmd_settings: + fork: holesky + port: 8545 + - name: Ganache-CLI + id: development + cmd: ganache-cli + host: http://127.0.0.1 + cmd_settings: + port: 8545 + gas_limit: 12000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + - name: Geth Dev + id: geth-dev + cmd: ethnode + host: http://127.0.0.1 + cmd_settings: + port: 8545 + - name: Hardhat + id: hardhat + cmd: npx hardhat node + host: http://localhost + cmd_settings: + port: 8545 + - name: Hardhat (Mainnet Fork) + id: hardhat-fork + cmd: npx hardhat node + host: http://localhost + timeout: 120 + cmd_settings: + port: 8545 + fork: mainnet + - name: Ganache-CLI (Mainnet Fork) + id: mainnet-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 12000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: mainnet + - name: Ganache-CLI (BSC-Mainnet Fork) + id: bsc-main-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 12000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: bsc-main + - name: Ganache-CLI (FTM-Mainnet Fork) + id: ftm-main-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 12000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: ftm-main + - name: Ganache-CLI (Polygon-Mainnet Fork) + id: polygon-main-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 20000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: polygon-main + - name: Ganache-CLI (Avax-Mainnet Fork) + id: avax-main-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 20000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: avax-main + - name: Ganache-CLI (Aurora-Mainnet Fork) + id: aurora-main-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 20000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: aurora-main + - name: Ganache-CLI (Gnosis-Mainnet Fork) + id: gnosis-main-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 20000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: gnosis-main + - name: Ganache-CLI (zkEVM-Mainnet Fork) + id: zkevm-main-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 20000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: zkevm-main + - name: Ganache-CLI Base-Mainnet Fork) + id: base-main-fork + cmd: ganache-cli + host: http://127.0.0.1 + timeout: 120 + cmd_settings: + port: 8545 + gas_limit: 20000000 + accounts: 10 + evm_version: istanbul + mnemonic: brownie + fork: base-main From 632de1cbd60242c5eb7408903db49f84086b48d4 Mon Sep 17 00:00:00 2001 From: KRogLA Date: Wed, 26 Jun 2024 03:03:09 +0500 Subject: [PATCH 029/220] fix: refactor vote scripts --- configs/config_holesky.py | 1 + scripts/holesky/vote_sr_v2_holesky.py | 440 ++++++++++++++------------ scripts/mainnet/vote_sr_v2_mainnet.py | 388 ++++++++++++++++------- vote_sr_v2_holesky.py | 280 ---------------- 4 files changed, 504 insertions(+), 605 deletions(-) delete mode 100644 vote_sr_v2_holesky.py diff --git a/configs/config_holesky.py b/configs/config_holesky.py index 92abe1410..9b9229d49 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -108,6 +108,7 @@ SANDBOX_APP_ID = "0x85d2fceef13a6c14c43527594f79fb91a8ef8f15024a43486efac8df2b11e632" SIMPLE_DVT = "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6" +SIMPLE_DVT_IMPL = "0x4d75529C753eef6e18F2D37D13508FC5035Ec95e" # same as for NOR SIMPLE_DVT_REPO = "0x889dB59baf032E1dfD4fCA720e0833c24f1404C6" SANDBOX = "0xD6C2ce3BB8bea2832496Ac8b5144819719f343AC" diff --git a/scripts/holesky/vote_sr_v2_holesky.py b/scripts/holesky/vote_sr_v2_holesky.py index e28973a3a..fe7f6e695 100644 --- a/scripts/holesky/vote_sr_v2_holesky.py +++ b/scripts/holesky/vote_sr_v2_holesky.py @@ -47,6 +47,7 @@ from utils.config import ( get_deployer_account, get_is_live, + get_priority_fee, contracts, NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, SIMPLE_DVT_ARAGON_APP_ID, @@ -56,23 +57,22 @@ ACCOUNTING_ORACLE_IMPL, NODE_OPERATORS_REGISTRY_IMPL, CS_ACCOUNTING_ADDRESS, - AGENT, - CS_ORACLE_HASH_CONSENSUS_ADDRESS, ) - +from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description from utils.repo import ( add_implementation_to_nor_app_repo, add_implementation_to_sdvt_app_repo, add_implementation_to_sandbox_app_repo, ) - +from utils.permissions import encode_oz_grant_role, encode_oz_revoke_role +from utils.easy_track import add_evmscript_factory, create_permissions from utils.kernel import update_app_implementation - from utils.voting import bake_vote_items, confirm_vote_script, create_vote from brownie.network.transaction import TransactionReceipt from utils.agent import agent_forward + # SR PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] @@ -84,7 +84,6 @@ VEBO_CONSENSUS_VERSION = 2 # CSM - CS_MODULE_NAME = "CommunityStaking" CS_STAKE_SHARE_LIMIT = 2000 CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 @@ -94,6 +93,10 @@ CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 CS_ORACLE_INITIAL_EPOCH = 58050 +description = """ +_REPLACE_ME_ +""" + def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: proxy = interface.OssifiableProxy(contracts.lido_locator) @@ -152,18 +155,6 @@ def get_repo_version(repo_address: str) -> tuple[int, int, int]: return contract["semanticVersion"] -def grantCsmResumeRoleToAgent() -> Tuple[str, str]: - - return ( - contracts.csm.address, - contracts.csm.grantRole.encode_input( - # keccak256 RESUME_ROLE - "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7", - contracts.agent.address, - ), - ) - - def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: """Prepare and run voting.""" @@ -175,211 +166,256 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T simple_dvt_uri = get_repo_uri(simple_dvt_repo) sandbox_uri = get_repo_uri(sandbox_repo) - call_script_items = [ + vote_desc_items, call_script_items = zip( + # # SR 2 - # 1) - agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), - # 2) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.revokeRole.encode_input( - # keccak256 STAKING_MODULE_PAUSE_ROLE - "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", - contracts.deposit_security_module_v2, - ), - ) - ] + # + ( + "1. Update locator implementation", + agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), ), - # 3) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.revokeRole.encode_input( - # keccak256 STAKING_MODULE_RESUME_ROLE - "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", - contracts.deposit_security_module_v2, - ), - ) - ] + ( + "2. Revoke pause role from old DSM", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_PAUSE_ROLE", + revoke_from=contracts.deposit_security_module_v2, + ) + ] + ), ), - # 4) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.grantRole.encode_input( - # keccak256 STAKING_MODULE_UNVETTING_ROLE - "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", - contracts.deposit_security_module, - ), - ) - ] + ( + "3. Revoke resume role from old DSM", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_RESUME_ROLE", + revoke_from=contracts.deposit_security_module_v2, + ) + ] + ), ), - # 5) - agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), - # 6) - encode_staking_router_finalize(), - # 7) - add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), - # 8) - update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 9) - encode_nor_finalize(), - # 10) - add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), - # 11) - update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 12) - encode_sdvt_finalize(), - # 13) - add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), - # 14) - update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 15) - encode_sandbox_finalize(), - # 16) - agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), - # 17) - encode_ao_finalize(), - # 18) - agent_forward( - [ - ( - contracts.validators_exit_bus_oracle.address, - contracts.validators_exit_bus_oracle.grantRole.encode_input( - # keccak256 MANAGE_CONSENSUS_VERSION_ROLE - "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", - contracts.agent.address, - ), - ) - ] + ( + "4. Grant unvetting role to new DSM", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_UNVETTING_ROLE", + grant_to=contracts.deposit_security_module, + ) + ] + ), ), - # 19) - agent_forward([encode_set_consensus_version()]), - # 20) - agent_forward( - [ - ( - contracts.validators_exit_bus_oracle.address, - contracts.validators_exit_bus_oracle.revokeRole.encode_input( - # keccak256 MANAGE_CONSENSUS_VERSION_ROLE - "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", - contracts.agent.address, - ), - ) - ] + ( + "5. Update SR implementation", + agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), + ), + ( + "6. Call finalize upgrade on SR", + encode_staking_router_finalize(), + ), + ( + "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), + ), + ( + "8. Update `NodeOperatorsRegistry` implementation", + update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + ), + ( + "9. Finalize NOR upgrade", + encode_nor_finalize(), + ), + ( + "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", + add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), + ), + ( + "11. Update `SimpleDVT` implementation", + update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), ), + ( + "12. Finalize SimpleDVT upgrade", + encode_sdvt_finalize(), + ), + ( + "13. Publish new `Sandbox` implementation in Sandbox app APM repo", + add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), + ), + ( + "14. Update `Sandbox` implementation", + update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + ), + ( + "15. Finalize Sandbox upgrade", + encode_sandbox_finalize(), + ), + ( + "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + ), + ( + "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + encode_ao_finalize(), + ), + ( + "18. Grant manage consensus role to agent ${AGENT}", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.validators_exit_bus_oracle, + role_name="MANAGE_CONSENSUS_VERSION_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + agent_forward([encode_set_consensus_version()]), + ), + ( + "20. Revoke manage consensus role from agent ${AGENT}", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.validators_exit_bus_oracle, + role_name="MANAGE_CONSENSUS_VERSION_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + # # CSM - # 21) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.grantRole.encode_input( - # STAKING_MODULE_MANAGE_ROLE - "0x3105bcbf19d4417b73ae0e58d508a65ecf75665e46c2622d8521732de6080c48", - contracts.agent.address, - ), - ) - ] + # + ( + "21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_MANAGE_ROLE", + grant_to=contracts.agent, + ) + ] + ), ), - # 22) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.addStakingModule.encode_input( - CS_MODULE_NAME, - contracts.csm.address, - CS_STAKE_SHARE_LIMIT, - CS_PRIORITY_EXIT_SHARE_THRESHOLD, - CS_STAKING_MODULE_FEE, - CS_TREASURY_FEE, - CS_MAX_DEPOSITS_PER_BLOCK, - CS_MIN_DEPOSIT_BLOCK_DISTANCE, + ( + "22. Add staking module", + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.addStakingModule.encode_input( + CS_MODULE_NAME, + contracts.csm.address, + CS_STAKE_SHARE_LIMIT, + CS_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_STAKING_MODULE_FEE, + CS_TREASURY_FEE, + CS_MAX_DEPOSITS_PER_BLOCK, + CS_MIN_DEPOSIT_BLOCK_DISTANCE, + ), ), - ), - ] + ] + ), ), - # 23) - agent_forward( - [ - ( - contracts.burner.address, - contracts.burner.grantRole.encode_input( - # keccak256 'REQUEST_BURN_SHARES_ROLE' - "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8", - CS_ACCOUNTING_ADDRESS, - ), - ) - ] + ( + "23. Grant request burn role to CSAccounting contract", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.burner, + role_name="REQUEST_BURN_SHARES_ROLE", + grant_to=CS_ACCOUNTING_ADDRESS, + ) + ] + ), + ), + ( + "24. Grant resume role to agent", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.csm, + role_name="RESUME_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "25. Resume staking module", + agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), + ), + ( + "26. Revoke resume role from agent", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.csm, + role_name="RESUME_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + ( + "27. Update initial epoch", + agent_forward( + [ + ( + contracts.csmHashConsensus.address, + contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), + ) + ] + ), ), - # 24) - # agent_forward([grantCsmResumeRoleToAgent()]), - # # 25) - # agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), - # # 26) # ( - # contracts.csm.address, - # contracts.csm.revokeRole.encode_input( - # "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7", contracts.agent.address + # "28. Add CS settle EL stealing factory to ET", + # add_evmscript_factory( + # factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, + # permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), # ), # ), - # # 27) - # (contracts.csmHashConsensus.address, contracts.csmHashConsensus.updateInitialEpoch(CS_ORACLE_INITIAL_EPOCH)), - # 28) - ] - - vote_desc_items = [ - "1. Update locator implementation", - "2. Revoke pause role from old DSM", - "3. Revoke resume role from old DSM", - "4. Grant unvetting role to new DSM", - "5. Update SR implementation", - "6. Call finalize upgrade on SR", - "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", - "8. Update `NodeOperatorsRegistry` implementation", - "9. Finalize NOR upgrade", - "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", - "11. Update `SimpleDVT` implementation", - "12. Finalize SimpleDVT upgrade", - "13. Publish new `Sandbox` implementation in Sandbox app APM repo", - "14. Update `Sandbox` implementation", - "15. Finalize Sandbox upgrade", - "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", - "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - "18. Grant manage consensus role to agent ${AGENT}", - "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", - "20. Revoke manage consensus role from agent ${AGENT}", - "21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE", - "22. Add staking module", - "23. Grant request burn role to CSAccounting contract", - # "24. Grant resume role to agent", - # "25. Resume staking module", - # "26. Revoke resume role from agent", - # "27. Update initial epoch", - # 28. Add CS settle EL stealing factory to ET - # 29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} - ] - - vote_items = bake_vote_items(vote_desc_items, call_script_items) - - return confirm_vote_script(vote_items, silent) and list(create_vote(vote_items, tx_params)) + ( + "29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT}", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_MANAGE_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + ) + + vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) + + if silent: + desc_ipfs = calculate_vote_ipfs_description(description) + else: + desc_ipfs = upload_vote_ipfs_description(description) + + return confirm_vote_script(vote_items, silent, desc_ipfs) and list( + create_vote(vote_items, tx_params, desc_ipfs=desc_ipfs) + ) def main(): tx_params = {"from": get_deployer_account()} if get_is_live(): - tx_params["max_fee"] = "300 gwei" - tx_params["priority_fee"] = "2 gwei" - - print(tx_params) + tx_params["priority_fee"] = get_priority_fee() - vote_id, _ = start_vote(tx_params=tx_params, silent=False) + vote_id, _ = start_vote(tx_params=tx_params, silent=True) # disable IPFS description for Holesky vote_id >= 0 and print(f"Vote created: {vote_id}.") diff --git a/scripts/mainnet/vote_sr_v2_mainnet.py b/scripts/mainnet/vote_sr_v2_mainnet.py index 20eec9293..558240ec2 100644 --- a/scripts/mainnet/vote_sr_v2_mainnet.py +++ b/scripts/mainnet/vote_sr_v2_mainnet.py @@ -12,11 +12,23 @@ 10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo 11. Update `SimpleDVT` implementation 12. Finalize SimpleDVT upgrade -16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, -17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, -18. Grant manage consensus role to agent ${AGENT}` -19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` -20. Revoke manage consensus role from agent ${AGENT}" +13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, +14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +15. Grant manage consensus role to agent ${AGENT}` +16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +17. Revoke manage consensus role from agent ${AGENT}" + +CSM + +18. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE +19. Add staking module +20. Grant request burn role to CSAccounting contract +21. Grant resume role to agent +22. Resume staking module +23. Revoke resume role from agent +24. Update initial epoch +25. Add CS settle EL stealing factory to ET +26. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} """ import time @@ -32,6 +44,7 @@ from utils.config import ( get_deployer_account, get_is_live, + get_priority_fee, contracts, NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, SIMPLE_DVT_ARAGON_APP_ID, @@ -39,22 +52,24 @@ STAKING_ROUTER_IMPL, ACCOUNTING_ORACLE_IMPL, NODE_OPERATORS_REGISTRY_IMPL, - AGENT, + CS_ACCOUNTING_ADDRESS, ) - +from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description from utils.repo import ( add_implementation_to_nor_app_repo, add_implementation_to_sdvt_app_repo, ) - +from utils.permissions import encode_oz_grant_role, encode_oz_revoke_role +from utils.easy_track import add_evmscript_factory, create_permissions from utils.kernel import update_app_implementation - from utils.voting import bake_vote_items, confirm_vote_script, create_vote from brownie.network.transaction import TransactionReceipt from utils.agent import agent_forward +# SR + PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000] MAX_DEPOSITS_PER_BLOCK = [50, 50] MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25] @@ -63,6 +78,20 @@ AO_CONSENSUS_VERSION = 2 VEBO_CONSENSUS_VERSION = 2 +# CSM +CS_MODULE_NAME = "CommunityStaking" +CS_STAKE_SHARE_LIMIT = 2000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 +CS_STAKING_MODULE_FEE = 800 +CS_TREASURY_FEE = 200 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 58050 + +description = """ +_REPLACE_ME_ +""" + def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: proxy = interface.OssifiableProxy(contracts.lido_locator) @@ -121,135 +150,248 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T nor_repo = contracts.nor_app_repo.address simple_dvt_repo = contracts.simple_dvt_app_repo.address + sandbox_repo = contracts.sandbox_repo.address nor_uri = get_repo_uri(nor_repo) simple_dvt_uri = get_repo_uri(simple_dvt_repo) - - call_script_items = [ - # 1) - agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), - # 2) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.revokeRole.encode_input( - # keccak256 STAKING_MODULE_PAUSE_ROLE - "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", - contracts.deposit_security_module_v2, - ), - ) - ] + sandbox_uri = get_repo_uri(sandbox_repo) + + vote_desc_items, call_script_items = zip( + # + # SR 2 + # + ( + "1. Update locator implementation", + agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), ), - # 3) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.revokeRole.encode_input( - # keccak256 STAKING_MODULE_RESUME_ROLE - "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", - contracts.deposit_security_module_v2, - ), - ) - ] + ( + "2. Revoke pause role from old DSM", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_PAUSE_ROLE", + revoke_from=contracts.deposit_security_module_v2, + ) + ] + ), ), - # 4) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.grantRole.encode_input( - # keccak256 STAKING_MODULE_UNVETTING_ROLE - "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", - contracts.deposit_security_module, - ), - ) - ] + ( + "3. Revoke resume role from old DSM", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_RESUME_ROLE", + revoke_from=contracts.deposit_security_module_v2, + ) + ] + ), ), - # 5) - agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), - # 6) - encode_staking_router_finalize(), - # 7) - add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), - # 8) - update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 9) - encode_nor_finalize(), - # 10) - add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), - # 11) - update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 12) - encode_sdvt_finalize(), - # 13) - agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), - # 14) - encode_ao_finalize(), - # 15) - agent_forward( - [ - ( - contracts.validators_exit_bus_oracle.address, - contracts.validators_exit_bus_oracle.grantRole.encode_input( - # keccak256 MANAGE_CONSENSUS_VERSION_ROLE - "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", - AGENT, - ), - ) - ] + ( + "4. Grant unvetting role to new DSM", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_UNVETTING_ROLE", + grant_to=contracts.deposit_security_module, + ) + ] + ), + ), + ( + "5. Update SR implementation", + agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), + ), + ( + "6. Call finalize upgrade on SR", + encode_staking_router_finalize(), + ), + ( + "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), + ), + ( + "8. Update `NodeOperatorsRegistry` implementation", + update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + ), + ( + "9. Finalize NOR upgrade", + encode_nor_finalize(), + ), + ( + "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", + add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), + ), + ( + "11. Update `SimpleDVT` implementation", + update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + ), + ( + "12. Finalize SimpleDVT upgrade", + encode_sdvt_finalize(), ), - # 16) - agent_forward([encode_set_consensus_version()]), - # 17) - agent_forward( - [ - ( - contracts.validators_exit_bus_oracle.address, - contracts.validators_exit_bus_oracle.revokeRole.encode_input( - # keccak256 MANAGE_CONSENSUS_VERSION_ROLE - "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", - AGENT, + ( + "13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + ), + ( + "14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + encode_ao_finalize(), + ), + ( + "15. Grant manage consensus role to agent ${AGENT}", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.validators_exit_bus_oracle, + role_name="MANAGE_CONSENSUS_VERSION_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + agent_forward([encode_set_consensus_version()]), + ), + ( + "17. Revoke manage consensus role from agent ${AGENT}", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.validators_exit_bus_oracle, + role_name="MANAGE_CONSENSUS_VERSION_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + # + # CSM + # + ( + "18. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_MANAGE_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "19. Add staking module", + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.addStakingModule.encode_input( + CS_MODULE_NAME, + contracts.csm.address, + CS_STAKE_SHARE_LIMIT, + CS_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_STAKING_MODULE_FEE, + CS_TREASURY_FEE, + CS_MAX_DEPOSITS_PER_BLOCK, + CS_MIN_DEPOSIT_BLOCK_DISTANCE, + ), ), - ) - ] + ] + ), + ), + ( + "20. Grant request burn role to CSAccounting contract", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.burner, + role_name="REQUEST_BURN_SHARES_ROLE", + grant_to=CS_ACCOUNTING_ADDRESS, + ) + ] + ), + ), + ( + "21. Grant resume role to agent", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.csm, + role_name="RESUME_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "22. Resume staking module", + agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), ), - ] - - vote_desc_items = [ - "1. Update locator implementation", - "2. Revoke pause role from old DSM", - "3. Revoke resume role from old DSM", - "4. Grant unvetting role to new DSM", - "5. Update SR implementation", - "6. Call finalize upgrade on SR", - "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", - "8. Update `NodeOperatorsRegistry` implementation", - "9. Finalize NOR upgrade", - "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", - "11. Update `SimpleDVT` implementation", - "12. Finalize SimpleDVT upgrade", - "13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", - "14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - "15. Grant manage consensus role to agent ${AGENT}", - "16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", - "17. Revoke manage consensus role from agent ${AGENT}", - ] - - vote_items = bake_vote_items(vote_desc_items, call_script_items) - - return confirm_vote_script(vote_items, silent) and list(create_vote(vote_items, tx_params)) + ( + "23. Revoke resume role from agent", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.csm, + role_name="RESUME_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + ( + "24. Update initial epoch", + agent_forward( + [ + ( + contracts.csmHashConsensus.address, + contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), + ) + ] + ), + ), + # ( + # "25. Add CS settle EL stealing factory to ET", + # add_evmscript_factory( + # factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, + # permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), + # ), + # ), + ( + "26. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT}", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_MANAGE_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + ) + + vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) + + if silent: + desc_ipfs = calculate_vote_ipfs_description(description) + else: + desc_ipfs = upload_vote_ipfs_description(description) + + return confirm_vote_script(vote_items, silent, desc_ipfs) and list( + create_vote(vote_items, tx_params, desc_ipfs=desc_ipfs) + ) def main(): tx_params = {"from": get_deployer_account()} if get_is_live(): - tx_params["max_fee"] = "300 gwei" - tx_params["priority_fee"] = "2 gwei" - - print(tx_params) + tx_params["priority_fee"] = get_priority_fee() vote_id, _ = start_vote(tx_params=tx_params, silent=False) diff --git a/vote_sr_v2_holesky.py b/vote_sr_v2_holesky.py deleted file mode 100644 index a73de64b1..000000000 --- a/vote_sr_v2_holesky.py +++ /dev/null @@ -1,280 +0,0 @@ -""" -SR V2 -1. Update locator implementation -2. Revoke pause role from old DSM -3. Revoke resume role from old DSM -4. Grant unvetting role to new DSM -5. Update SR implementation -6. Call finalize upgrade on SR -7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo -8. Update `NodeOperatorsRegistry` implementation -9. Finalize NOR upgrade -10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo -11. Update `SimpleDVT` implementation -12. Finalize SimpleDVT upgrade -13. Publish new `Sandbox` implementation in Sandbox app APM repo -14. Update `Sandbox` implementation -15. Finalize Sandbox upgrade -16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, -17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, -18. Grant manage consensus role to agent ${AGENT}` -19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` -20. Revoke manage consensus role from agent ${AGENT}" -""" - -import time - -try: - from brownie import interface, accounts -except ImportError: - print("You're probably running inside Brownie console. Please call:") - print("set_console_globals(interface=interface)") - - -from typing import Dict, Tuple, Optional -from utils.config import ( - get_deployer_account, - get_is_live, - contracts, - NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, - SIMPLE_DVT_ARAGON_APP_ID, - SANDBOX_APP_ID, - LIDO_LOCATOR_IMPL, - STAKING_ROUTER_IMPL, - ACCOUNTING_ORACLE_IMPL, - NODE_OPERATORS_REGISTRY_IMPL, - AGENT, -) - -from utils.repo import ( - add_implementation_to_nor_app_repo, - add_implementation_to_sdvt_app_repo, - add_implementation_to_sandbox_app_repo, -) - -from utils.kernel import update_app_implementation - -from utils.voting import bake_vote_items, confirm_vote_script, create_vote - -from brownie.network.transaction import TransactionReceipt -from utils.agent import agent_forward - - -PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] -MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] -MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] -NOR_VERSION = ["2", "0", "0"] -SDVT_VERSION = ["2", "0", "0"] -SANDBOX_VERSION = ["2", "0", "0"] -AO_CONSENSUS_VERSION = 2 -VEBO_CONSENSUS_VERSION = 2 - - -def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.lido_locator) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_staking_router_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.staking_router) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_staking_router_finalize() -> Tuple[str, str]: - proxy = interface.StakingRouter(contracts.staking_router) - return proxy.address, proxy.finalizeUpgrade_v2.encode_input( - PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES - ) - - -def encode_nor_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.node_operators_registry) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_sdvt_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.simple_dvt) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_sandbox_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.sandbox) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.accounting_oracle) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_ao_finalize() -> Tuple[str, str]: - proxy = interface.AccountingOracle(contracts.accounting_oracle) - return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) - - -def encode_set_consensus_version() -> Tuple[str, str]: - proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) - return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) - - -def get_repo_uri(repo_address: str) -> str: - contract = interface.Repo(repo_address).getLatest() - return contract["contentURI"] - - -def get_repo_version(repo_address: str) -> tuple[int, int, int]: - contract = interface.Repo(repo_address).getLatest() - return contract["semanticVersion"] - - -def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: - """Prepare and run voting.""" - - nor_repo = contracts.nor_app_repo.address - simple_dvt_repo = contracts.simple_dvt_app_repo.address - sandbox_repo = contracts.sandbox_repo.address - - nor_uri = get_repo_uri(nor_repo) - simple_dvt_uri = get_repo_uri(simple_dvt_repo) - sandbox_uri = get_repo_uri(sandbox_repo) - - call_script_items = [ - # 1) - agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), - # 2) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.revokeRole.encode_input( - # keccak256 STAKING_MODULE_PAUSE_ROLE - "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e", - contracts.deposit_security_module_v2, - ), - ) - ] - ), - # 3) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.revokeRole.encode_input( - # keccak256 STAKING_MODULE_RESUME_ROLE - "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2", - contracts.deposit_security_module_v2, - ), - ) - ] - ), - # 4) - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.grantRole.encode_input( - # keccak256 STAKING_MODULE_UNVETTING_ROLE - "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57", - contracts.deposit_security_module, - ), - ) - ] - ), - # 5) - agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), - # 6) - encode_staking_router_finalize(), - # 7) - add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), - # 8) - update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 9) - encode_nor_finalize(), - # 10) - add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), - # 11) - update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 12) - encode_sdvt_finalize(), - # 13) - add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), - # 14) - update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - # 15) - encode_sandbox_finalize(), - # 16) - agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), - # 17) - encode_ao_finalize(), - # 18) - agent_forward( - [ - ( - contracts.validators_exit_bus_oracle.address, - contracts.validators_exit_bus_oracle.grantRole.encode_input( - # keccak256 MANAGE_CONSENSUS_VERSION_ROLE - "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", - AGENT, - ), - ) - ] - ), - # 19) - agent_forward([encode_set_consensus_version()]), - # 20) - agent_forward( - [ - ( - contracts.validators_exit_bus_oracle.address, - contracts.validators_exit_bus_oracle.revokeRole.encode_input( - # keccak256 MANAGE_CONSENSUS_VERSION_ROLE - "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341", - AGENT, - ), - ) - ] - ), - ] - - vote_desc_items = [ - "1. Update locator implementation", - "2. Revoke pause role from old DSM", - "3. Revoke resume role from old DSM", - "4. Grant unvetting role to new DSM", - "5. Update SR implementation", - "6. Call finalize upgrade on SR", - "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", - "8. Update `NodeOperatorsRegistry` implementation", - "9. Finalize NOR upgrade", - "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", - "11. Update `SimpleDVT` implementation", - "12. Finalize SimpleDVT upgrade", - "13. Publish new `Sandbox` implementation in Sandbox app APM repo", - "14. Update `Sandbox` implementation", - "15. Finalize Sandbox upgrade", - "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", - "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - "18. Grant manage consensus role to agent ${AGENT}", - "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", - "20. Revoke manage consensus role from agent ${AGENT}", - ] - - vote_items = bake_vote_items(vote_desc_items, call_script_items) - - return confirm_vote_script(vote_items, silent) and list(create_vote(vote_items, tx_params)) - - -def main(): - tx_params = {"from": get_deployer_account()} - - if get_is_live(): - tx_params["max_fee"] = "300 gwei" - tx_params["priority_fee"] = "2 gwei" - - print(tx_params) - - vote_id, _ = start_vote(tx_params=tx_params, silent=False) - - vote_id >= 0 and print(f"Vote created: {vote_id}.") - - time.sleep(5) # hack for waiting thread #2. From 43e575f4a003346cab0a291d47efaa8fea145657 Mon Sep 17 00:00:00 2001 From: KRogLA Date: Wed, 26 Jun 2024 03:03:30 +0500 Subject: [PATCH 030/220] fix: add holesky vote test --- tests/test_vote_sr_v2_holesky.py | 468 +++++++++++++++++++++++++++++++ 1 file changed, 468 insertions(+) create mode 100644 tests/test_vote_sr_v2_holesky.py diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py new file mode 100644 index 000000000..2d954cfe5 --- /dev/null +++ b/tests/test_vote_sr_v2_holesky.py @@ -0,0 +1,468 @@ +import pytest + +from utils.config import ( + contracts, + get_priority_fee, + STAKING_ROUTER_IMPL, + LIDO_LOCATOR_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, + NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + SIMPLE_DVT_ARAGON_APP_ID, + SIMPLE_DVT_IMPL, + ACCOUNTING_ORACLE_IMPL, +) +from scripts.vote_sr_v2_holesky import start_vote +from utils.config import ( + contracts, + LDO_HOLDER_ADDRESS_FOR_TESTS, +) +from brownie import interface, Contract +from utils.test.tx_tracing_helpers import * +from utils.test.event_validators.permission import validate_grant_role_event, validate_revoke_role_event +from utils.test.event_validators.common import validate_events_chain +from utils.test.event_validators.repo_upgrade import validate_repo_upgrade_event, RepoUpgrade +from utils.test.event_validators.aragon import validate_app_update_event +from typing import NamedTuple + +class StakingModuleItem(NamedTuple): + id: int + staking_module_fee: int + stake_share_limit: int + treasury_fee: int + priority_exit_share_threshold: int + max_deposits_per_block: int + min_deposit_block_distance: int + + +STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" +PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" +STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" +MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" +OLD_LOCATOR_IMPL_ADDRESS = "0xDba5Ad530425bb1b14EECD76F1b4a517780de537" +OLD_SR_IMPL_ADDRESS = "0x32f236423928c2c138f46351d9e5fd26331b1aa4" +OLD_NOR_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" +OLD_SDVT_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" +OLD_ACCOUNTING_ORACLE_IMPL = "0x6aca050709469f1f98d8f40f68b1c83b533cd2b2" +CURATED_MODULE_ID = 1 +SIMPLE_DVT_MODULE_ID = 2 +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 + +SR_VERSION = 2 +NOR_VERSION = 3 +DISTRIBUTED = 2 +SDVT_VERSION = 3 +AO_VERSION = 2 + +# new added fields +CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 +CURATED_MAX_DEPOSITS_PER_BLOCK = 50 +CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 +SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 +SDVT_MAX_DEPOSITS_PER_BLOCK = 50 +SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 + +old_nor_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" +old_sdvt_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" + +CURATED_MODULE_BEFORE_VOTE = { + "id": 1, + "name": "curated-onchain-v1", + "stakingModuleFee": 500, + "treasuryFee": 500, + "targetShare": 10000, + "priorityExitShareThreshold": None, + "maxDepositsPerBlock": None, + "minDepositBlockDistance": None, +} + +SDVT_MODULE_BEFORE_VOTE = { + "id": 2, + "name": "SimpleDVT", + "stakingModuleAddress": "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "stakingModuleFee": 800, + "treasuryFee": 200, + "targetShare": 5000, + "priorityExitShareThreshold": None, + "maxDepositsPerBlock": None, + "minDepositBlockDistance": None, +} + +CURATED_MODULE_AFTER_VOTE = CURATED_MODULE_BEFORE_VOTE.copy() +CURATED_MODULE_AFTER_VOTE.update( + { + "priorityExitShareThreshold": CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, + "maxDepositsPerBlock": CURATED_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, + } +) + +SDVT_MODULE_AFTER_VOTE = SDVT_MODULE_BEFORE_VOTE.copy() +SDVT_MODULE_AFTER_VOTE.update( + { + "priorityExitShareThreshold": SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS, + "maxDepositsPerBlock": SDVT_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": SDVT_MIN_DEPOSIT_BLOCK_DISTANCES, + } +) + +OLD_SR_ABI = bi = [ + { + "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], + "name": "getStakingModule", + "outputs": [ + { + "components": [ + {"internalType": "uint24", "name": "id", "type": "uint24"}, + {"internalType": "address", "name": "stakingModuleAddress", "type": "address"}, + {"internalType": "uint16", "name": "stakingModuleFee", "type": "uint16"}, + {"internalType": "uint16", "name": "treasuryFee", "type": "uint16"}, + {"internalType": "uint16", "name": "stakeShareLimit", "type": "uint16"}, + {"internalType": "uint8", "name": "status", "type": "uint8"}, + {"internalType": "string", "name": "name", "type": "string"}, + {"internalType": "uint64", "name": "lastDepositAt", "type": "uint64"}, + {"internalType": "uint256", "name": "lastDepositBlock", "type": "uint256"}, + {"internalType": "uint256", "name": "exitedValidatorsCount", "type": "uint256"}, + ], + "internalType": "struct StakingRouter.StakingModule", + "name": "", + "type": "tuple", + } + ], + "stateMutability": "view", + "type": "function", + } +] + + +def test_vote( + helpers, + accounts, + vote_ids_from_env, +): + staking_router = contracts.staking_router + + sr_proxy = interface.OssifiableProxy(contracts.staking_router) + locator_proxy = interface.OssifiableProxy(contracts.lido_locator) + nor_proxy = interface.AppProxyUpgradeable(contracts.node_operators_registry) + sdvt_proxy = interface.AppProxyUpgradeable(contracts.simple_dvt) + ao_proxy = interface.OssifiableProxy(contracts.accounting_oracle) + vebo_proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) + + assert staking_router.getStakingModulesCount() == 3 # curated + simpledvt + sandbox + + # Before voting tests + # locator + check_ossifiable_proxy_impl(locator_proxy, OLD_LOCATOR_IMPL_ADDRESS) + # DSM + check_dsm_roles_before_vote() + # SR + check_ossifiable_proxy_impl(sr_proxy, OLD_SR_IMPL_ADDRESS) + check_module_before_vote(CURATED_MODULE_BEFORE_VOTE) + check_module_before_vote(SDVT_MODULE_BEFORE_VOTE) + # NOR + nor_old_app = contracts.nor_app_repo.getLatest() + assert nor_proxy.implementation() == OLD_NOR_IMPL + assert_repo_before_vote(nor_old_app, 1, OLD_NOR_IMPL, old_nor_uri) + # SDVT + sdvt_old_app = contracts.simple_dvt_app_repo.getLatest() + assert sdvt_proxy.implementation() == OLD_SDVT_IMPL + assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, sdvt_uri) + # AO + check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) + # no prermission to manage consensus version on agent + check_manage_consensus_role() + + # VEBO consensus version + assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 + + # START VOTE + if len(vote_ids_from_env) > 0: + (vote_id,) = vote_ids_from_env + else: + tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS, "priority_fee": get_priority_fee()} + vote_id, _ = start_vote(tx_params, silent=True) + + vote_tx = helpers.execute_vote(accounts, vote_id, contracts.voting) + + print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") + + # locator + check_ossifiable_proxy_impl(locator_proxy, LIDO_LOCATOR_IMPL) + # DSM + check_dsm_roles_after_vote() + # SR + check_ossifiable_proxy_impl(sr_proxy, STAKING_ROUTER_IMPL) + check_module_after_vote(CURATED_MODULE_AFTER_VOTE) + check_module_after_vote(SDVT_MODULE_AFTER_VOTE) + # AO + check_ossifiable_proxy_impl(ao_proxy, ACCOUNTING_ORACLE_IMPL) + + # no prermission to manage consensus version on agent + check_manage_consensus_role() + # VEBO consensus version + assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION + + # Events check + events = group_voting_events(vote_tx) + + assert len(events) == 17 + + validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) + validate_dsm_roles_events(events) + validate_upgrade_events(events[4], STAKING_ROUTER_IMPL) + + validate_staking_module_update( + events[5], + [ + StakingModuleItem( + CURATED_MODULE_AFTER_VOTE["id"], + CURATED_MODULE_AFTER_VOTE["stakingModuleFee"], + CURATED_MODULE_AFTER_VOTE["targetShare"], + CURATED_MODULE_AFTER_VOTE["treasuryFee"], + CURATED_MODULE_AFTER_VOTE["priorityExitShareThreshold"], + CURATED_MODULE_AFTER_VOTE["maxDepositsPerBlock"], + CURATED_MODULE_AFTER_VOTE["minDepositBlockDistance"], + ), + StakingModuleItem( + SDVT_MODULE_AFTER_VOTE["id"], + SDVT_MODULE_AFTER_VOTE["stakingModuleFee"], + SDVT_MODULE_AFTER_VOTE["targetShare"], + SDVT_MODULE_AFTER_VOTE["treasuryFee"], + SDVT_MODULE_AFTER_VOTE["priorityExitShareThreshold"], + SDVT_MODULE_AFTER_VOTE["maxDepositsPerBlock"], + SDVT_MODULE_AFTER_VOTE["minDepositBlockDistance"], + ), + ], + ) + + nor_new_app = contracts.nor_app_repo.getLatest() + assert_repo_update(nor_new_app, nor_old_app, NODE_OPERATORS_REGISTRY_IMPL, nor_uri) + validate_repo_upgrade_event(events[6], RepoUpgrade(6, nor_new_app[0])) + validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL) + validate_nor_update(events[8], NOR_VERSION) + + sdvt_new_app = contracts.simple_dvt_app_repo.getLatest() + assert_repo_update(sdvt_new_app, sdvt_old_app, SIMPLE_DVT_IMPL, sdvt_uri) + validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) + validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL) + validate_nor_update(events[11], SDVT_VERSION) + + # AO + validate_upgrade_events(events[12], ACCOUNTING_ORACLE_IMPL) + validate_ao_update(events[13], AO_VERSION, AO_CONSENSUS_VERSION) + + validate_grant_role_event( + events[14], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + ) + + validate_vebo_consensus_version_set(events[15]) + + validate_revoke_role_event( + events[16], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + ) + + +def check_ossifiable_proxy_impl(proxy, expected_impl): + current_impl_address = proxy.proxy__getImplementation() + assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" + + +def check_dsm_roles_before_vote(): + new_dsm_doesnt_have_unvet_role = contracts.staking_router.hasRole( + STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module + ) + assert not new_dsm_doesnt_have_unvet_role + + old_dsm_has_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) + + assert old_dsm_has_pause_role + + # print(contracts.staking_router) + # print(contracts.deposit_security_module_v2) + # old_dsm_has_resume_role = contracts.staking_router.hasRole( + # STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 + # ) + + # assert old_dsm_has_resume_role + + +def check_dsm_roles_after_vote(): + new_dsm_has_unvet_role = contracts.staking_router.hasRole( + STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module + ) + assert new_dsm_has_unvet_role + + old_dsm_doesnt_have_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) + assert not old_dsm_doesnt_have_pause_role + + old_dsm_doesnt_have_resume_role = contracts.staking_router.hasRole( + STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 + ) + assert not old_dsm_doesnt_have_resume_role + + +def check_manage_consensus_role(): + agent_has_manage_consensus_role = contracts.validators_exit_bus_oracle.hasRole( + MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address + ) + assert not agent_has_manage_consensus_role + + +def check_module_before_vote(expected_module_data: Dict): + sr_contract = Contract.from_abi("StakingContract", contracts.staking_router.address, OLD_SR_ABI) + module = sr_contract.getStakingModule(expected_module_data["id"]) + assert module["id"] == expected_module_data["id"] + assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] + assert module["treasuryFee"] == expected_module_data["treasuryFee"] + assert module["stakeShareLimit"] == expected_module_data["targetShare"] + assert "priorityExitShareThreshold" not in module + assert "maxDepositsPerBlock" not in module + assert "minDepositBlockDistance" not in module + + +def check_module_after_vote(expected_module_data: Dict): + module = contracts.staking_router.getStakingModule(expected_module_data["id"]) + assert module["id"] == expected_module_data["id"] + assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] + assert module["treasuryFee"] == expected_module_data["treasuryFee"] + assert module["stakeShareLimit"] == expected_module_data["targetShare"] + assert module["priorityExitShareThreshold"] == expected_module_data["priorityExitShareThreshold"] + assert module["maxDepositsPerBlock"] == expected_module_data["maxDepositsPerBlock"] + assert module["minDepositBlockDistance"] == expected_module_data["minDepositBlockDistance"] + + +def assert_repo_before_vote(old_app, version, contract_address, old_content_uri): + assert old_app[0][0] == version + assert old_app[2] == old_content_uri, "Content uri before vote is wrong" + assert old_app[1] == contract_address, "New address should match" + + +def assert_repo_update(new_app, old_app, contract_address, old_content_uri): + assert old_app[1] != new_app[1], "Address should change" + assert new_app[1] == contract_address, "New address should match" + assert new_app[0][0] == old_app[0][0] + 1, "Major version should increment" + assert old_app[2] == new_app[2], "Content uri should not be changed" + assert new_app[2] == old_content_uri, "Content uri should match" + + +# Events check + + +def validate_upgrade_events(events: EventDict, implementation: str): + _events_chain = ["LogScriptCall", "LogScriptCall", "Upgraded", "ScriptResult"] + validate_events_chain([e.name for e in events], _events_chain) + assert events.count("Upgraded") == 1 + assert events["Upgraded"]["implementation"] == implementation, "Wrong withdrawal vault proxy implementation" + + +def validate_dsm_roles_events(events: EventDict): + validate_revoke_role_event( + events[1], PAUSE_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address + ) + validate_revoke_role_event( + events[2], STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address + ) + + validate_grant_role_event( + events[3], STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module.address, contracts.agent.address + ) + + +def validate_staking_module_update(event: EventDict, module_items: List[StakingModuleItem]): + assert len(module_items) == 2 + + _events_chain = [ + "LogScriptCall", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ContractVersionSet", + ] + + validate_events_chain([e.name for e in event], _events_chain) + + assert event.count("StakingModuleFeesSet") == 2 + assert event.count("StakingModuleShareLimitSet") == 2 + assert event.count("StakingModuleMinDepositBlockDistanceSet") == 2 + assert event.count("StakingModuleMaxDepositsPerBlockSet") == 2 + assert event.count("ContractVersionSet") == 1 + + # curated + assert event["StakingModuleShareLimitSet"][0]["stakingModuleId"] == module_items[0].id + assert event["StakingModuleShareLimitSet"][0]["stakeShareLimit"] == module_items[0].stake_share_limit + assert ( + event["StakingModuleShareLimitSet"][0]["priorityExitShareThreshold"] + == module_items[0].priority_exit_share_threshold + ) + assert event["StakingModuleFeesSet"][0]["stakingModuleId"] == module_items[0].id + assert event["StakingModuleFeesSet"][0]["stakingModuleFee"] == module_items[0].staking_module_fee + assert event["StakingModuleFeesSet"][0]["treasuryFee"] == module_items[0].treasury_fee + + assert ( + event["StakingModuleMaxDepositsPerBlockSet"][0]["maxDepositsPerBlock"] == module_items[0].max_deposits_per_block + ) + + assert ( + event["StakingModuleMinDepositBlockDistanceSet"][0]["minDepositBlockDistance"] + == module_items[0].min_deposit_block_distance + ) + + assert event["ContractVersionSet"]["version"] == SR_VERSION + + assert event["StakingModuleShareLimitSet"][1]["stakingModuleId"] == module_items[1].id + assert event["StakingModuleShareLimitSet"][1]["stakeShareLimit"] == module_items[1].stake_share_limit + assert ( + event["StakingModuleShareLimitSet"][1]["priorityExitShareThreshold"] + == module_items[1].priority_exit_share_threshold + ) + assert event["StakingModuleFeesSet"][1]["stakingModuleId"] == module_items[1].id + assert event["StakingModuleFeesSet"][1]["stakingModuleFee"] == module_items[1].staking_module_fee + assert event["StakingModuleFeesSet"][1]["treasuryFee"] == module_items[1].treasury_fee + + assert ( + event["StakingModuleMaxDepositsPerBlockSet"][1]["maxDepositsPerBlock"] == module_items[1].max_deposits_per_block + ) + + assert ( + event["StakingModuleMinDepositBlockDistanceSet"][1]["minDepositBlockDistance"] + == module_items[1].min_deposit_block_distance + ) + + +def validate_nor_update(event: EventDict, version): + _events_chain = [ + "LogScriptCall", + "ContractVersionSet", + "RewardDistributionStateChanged", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["ContractVersionSet"]["version"] == version + assert event["RewardDistributionStateChanged"]["state"] == DISTRIBUTED + + +def validate_ao_update(event: EventDict, version, ao_consensus_version): + _events_chain = [ + "LogScriptCall", + "ContractVersionSet", + "ConsensusVersionSet", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["ContractVersionSet"]["version"] == version + assert event["ConsensusVersionSet"]["version"] == ao_consensus_version + assert event["ConsensusVersionSet"]["prevVersion"] == ao_consensus_version - 1 + + +def validate_vebo_consensus_version_set(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "ConsensusVersionSet", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event["ConsensusVersionSet"]["version"] == VEBO_CONSENSUS_VERSION From 1122e60cf7c6a4bf57c1b8fbfd1effc1759e711c Mon Sep 17 00:00:00 2001 From: KRogLA Date: Wed, 26 Jun 2024 03:06:23 +0500 Subject: [PATCH 031/220] fix: vote script paths --- tests/test_vote_sr_v2_holesky.py | 2 +- tests/test_vote_sr_v2_mainnet.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 2d954cfe5..d206ccc25 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -11,7 +11,7 @@ SIMPLE_DVT_IMPL, ACCOUNTING_ORACLE_IMPL, ) -from scripts.vote_sr_v2_holesky import start_vote +from scripts.holesky.vote_sr_v2_holesky import start_vote from utils.config import ( contracts, LDO_HOLDER_ADDRESS_FOR_TESTS, diff --git a/tests/test_vote_sr_v2_mainnet.py b/tests/test_vote_sr_v2_mainnet.py index d5a35776f..3d49c1180 100644 --- a/tests/test_vote_sr_v2_mainnet.py +++ b/tests/test_vote_sr_v2_mainnet.py @@ -10,7 +10,7 @@ SIMPLE_DVT_IMPL, ACCOUNTING_ORACLE_IMPL, ) -from scripts.vote_sr_v2_mainnet import start_vote +from scripts.mainnet.vote_sr_v2_mainnet import start_vote from utils.config import ( contracts, LDO_HOLDER_ADDRESS_FOR_TESTS, From f9cd31d6905f05ce523758e4785064a4c6969da8 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 26 Jun 2024 16:41:28 +0200 Subject: [PATCH 032/220] feat: update interfaces --- interfaces/AccountingOracle.json | 2700 ++++++++--------- interfaces/DepositSecurityModule.json | 477 ++- interfaces/NodeOperatorsRegistry.json | 3266 ++++++++++----------- interfaces/OracleReportSanityChecker.json | 1383 ++++++++- 4 files changed, 4760 insertions(+), 3066 deletions(-) diff --git a/interfaces/AccountingOracle.json b/interfaces/AccountingOracle.json index f422cbaa0..069da4f74 100644 --- a/interfaces/AccountingOracle.json +++ b/interfaces/AccountingOracle.json @@ -1,1351 +1,1351 @@ [ - { - "inputs": [ - { - "internalType": "address", - "name": "lidoLocator", - "type": "address" - }, - { - "internalType": "address", - "name": "lido", - "type": "address" - }, - { - "internalType": "address", - "name": "legacyOracle", - "type": "address" - }, - { - "internalType": "uint256", - "name": "secondsPerSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "genesisTime", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "AddressCannotBeSame", - "type": "error" - }, - { - "inputs": [], - "name": "AddressCannotBeZero", - "type": "error" - }, - { - "inputs": [], - "name": "AdminCannotBeZero", - "type": "error" - }, - { - "inputs": [], - "name": "CannotSubmitExtraDataBeforeMainData", - "type": "error" - }, - { - "inputs": [], - "name": "ExtraDataAlreadyProcessed", - "type": "error" - }, - { - "inputs": [], - "name": "ExtraDataHashCannotBeZeroForNonEmptyData", - "type": "error" - }, - { - "inputs": [], - "name": "ExtraDataItemsCountCannotBeZeroForNonEmptyData", - "type": "error" - }, - { - "inputs": [], - "name": "HashCannotBeZero", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "code", - "type": "uint256" - } - ], - "name": "IncorrectOracleMigration", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "initialRefSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "processingRefSlot", - "type": "uint256" - } - ], - "name": "InitialRefSlotCannotBeLessThanProcessingOne", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidContractVersionIncrement", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidExitedValidatorsData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "itemIndex", - "type": "uint256" - } - ], - "name": "InvalidExtraDataItem", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "itemIndex", - "type": "uint256" - } - ], - "name": "InvalidExtraDataSortOrder", - "type": "error" - }, - { - "inputs": [], - "name": "LegacyOracleCannotBeZero", - "type": "error" - }, - { - "inputs": [], - "name": "LidoCannotBeZero", - "type": "error" - }, - { - "inputs": [], - "name": "LidoLocatorCannotBeZero", - "type": "error" - }, - { - "inputs": [], - "name": "NoConsensusReportToProcess", - "type": "error" - }, - { - "inputs": [], - "name": "NonZeroContractVersionOnInit", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "ProcessingDeadlineMissed", - "type": "error" - }, - { - "inputs": [], - "name": "RefSlotAlreadyProcessing", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "prevRefSlot", - "type": "uint256" - } - ], - "name": "RefSlotCannotDecrease", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "processingRefSlot", - "type": "uint256" - } - ], - "name": "RefSlotMustBeGreaterThanProcessingOne", - "type": "error" - }, - { - "inputs": [], - "name": "SecondsPerSlotCannotBeZero", - "type": "error" - }, - { - "inputs": [], - "name": "SenderIsNotTheConsensusContract", - "type": "error" - }, - { - "inputs": [], - "name": "SenderNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "UnexpectedChainConfig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expectedVersion", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "receivedVersion", - "type": "uint256" - } - ], - "name": "UnexpectedConsensusVersion", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - } - ], - "name": "UnexpectedContractVersion", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "consensusHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "receivedHash", - "type": "bytes32" - } - ], - "name": "UnexpectedDataHash", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expectedFormat", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "receivedFormat", - "type": "uint256" - } - ], - "name": "UnexpectedExtraDataFormat", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "consensusHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "receivedHash", - "type": "bytes32" - } - ], - "name": "UnexpectedExtraDataHash", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expectedIndex", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "receivedIndex", - "type": "uint256" - } - ], - "name": "UnexpectedExtraDataIndex", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expectedCount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "receivedCount", - "type": "uint256" - } - ], - "name": "UnexpectedExtraDataItemsCount", - "type": "error" - }, - { - "inputs": [], - "name": "UnexpectedExtraDataLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "consensusRefSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dataRefSlot", - "type": "uint256" - } - ], - "name": "UnexpectedRefSlot", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "format", - "type": "uint256" - } - ], - "name": "UnsupportedExtraDataFormat", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "itemIndex", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "dataType", - "type": "uint256" - } - ], - "name": "UnsupportedExtraDataType", - "type": "error" - }, - { - "inputs": [], - "name": "VersionCannotBeSame", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "prevAddr", - "type": "address" - } - ], - "name": "ConsensusHashContractSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "version", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "prevVersion", - "type": "uint256" - } - ], - "name": "ConsensusVersionSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "version", - "type": "uint256" - } - ], - "name": "ContractVersionSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "itemsProcessed", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "itemsCount", - "type": "uint256" - } - ], - "name": "ExtraDataSubmitted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" - } - ], - "name": "ProcessingStarted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" - } - ], - "name": "ReportDiscarded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "processingDeadlineTime", - "type": "uint256" - } - ], - "name": "ReportSubmitted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "processedItemsCount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "itemsCount", - "type": "uint256" - } - ], - "name": "WarnExtraDataIncompleteProcessing", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - } - ], - "name": "WarnProcessingMissed", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "EXTRA_DATA_FORMAT_EMPTY", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "EXTRA_DATA_FORMAT_LIST", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "EXTRA_DATA_TYPE_EXITED_VALIDATORS", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "EXTRA_DATA_TYPE_STUCK_VALIDATORS", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "GENESIS_TIME", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "LEGACY_ORACLE", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "LIDO", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "LOCATOR", - "outputs": [ - { - "internalType": "contract ILidoLocator", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MANAGE_CONSENSUS_CONTRACT_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MANAGE_CONSENSUS_VERSION_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SECONDS_PER_SLOT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SUBMIT_DATA_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - } - ], - "name": "discardConsensusReport", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "consensusVersion", - "type": "uint256" - } - ], - "name": "finalizeUpgrade_v2", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getConsensusContract", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getConsensusReport", - "outputs": [ - { - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "processingDeadlineTime", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "processingStarted", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getConsensusVersion", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getContractVersion", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getLastProcessingRefSlot", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getProcessingState", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "currentFrameRefSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "processingDeadlineTime", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "mainDataHash", - "type": "bytes32" - }, - { - "internalType": "bool", - "name": "mainDataSubmitted", - "type": "bool" - }, - { - "internalType": "bytes32", - "name": "extraDataHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "extraDataFormat", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "extraDataSubmitted", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "extraDataItemsCount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "extraDataItemsSubmitted", - "type": "uint256" - } - ], - "internalType": "struct AccountingOracle.ProcessingState", - "name": "result", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "getRoleMember", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleMemberCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "admin", - "type": "address" - }, - { - "internalType": "address", - "name": "consensusContract", - "type": "address" - }, - { - "internalType": "uint256", - "name": "consensusVersion", - "type": "uint256" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "admin", - "type": "address" - }, - { - "internalType": "address", - "name": "consensusContract", - "type": "address" - }, - { - "internalType": "uint256", - "name": "consensusVersion", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lastProcessingRefSlot", - "type": "uint256" - } - ], - "name": "initializeWithoutMigration", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "setConsensusContract", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "version", - "type": "uint256" - } - ], - "name": "setConsensusVersion", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "reportHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "submitConsensusReport", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "consensusVersion", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValidators", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "clBalanceGwei", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "stakingModuleIdsWithNewlyExitedValidators", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "numExitedValidatorsByStakingModule", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "withdrawalVaultBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "elRewardsVaultBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "sharesRequestedToBurn", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "withdrawalFinalizationBatches", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "simulatedShareRate", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "isBunkerMode", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "extraDataFormat", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "extraDataHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "extraDataItemsCount", - "type": "uint256" - } - ], - "internalType": "struct AccountingOracle.ReportData", - "name": "data", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "contractVersion", - "type": "uint256" - } - ], - "name": "submitReportData", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "submitReportExtraDataEmpty", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "submitReportExtraDataList", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ] \ No newline at end of file + { + "inputs": [ + { + "internalType": "address", + "name": "lidoLocator", + "type": "address" + }, + { + "internalType": "address", + "name": "lido", + "type": "address" + }, + { + "internalType": "address", + "name": "legacyOracle", + "type": "address" + }, + { + "internalType": "uint256", + "name": "secondsPerSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "genesisTime", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AddressCannotBeSame", + "type": "error" + }, + { + "inputs": [], + "name": "AddressCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "AdminCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "CannotSubmitExtraDataBeforeMainData", + "type": "error" + }, + { + "inputs": [], + "name": "ExtraDataAlreadyProcessed", + "type": "error" + }, + { + "inputs": [], + "name": "ExtraDataHashCannotBeZeroForNonEmptyData", + "type": "error" + }, + { + "inputs": [], + "name": "ExtraDataItemsCountCannotBeZeroForNonEmptyData", + "type": "error" + }, + { + "inputs": [], + "name": "HashCannotBeZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "code", + "type": "uint256" + } + ], + "name": "IncorrectOracleMigration", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "initialRefSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingRefSlot", + "type": "uint256" + } + ], + "name": "InitialRefSlotCannotBeLessThanProcessingOne", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidContractVersionIncrement", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidExitedValidatorsData", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "itemIndex", + "type": "uint256" + } + ], + "name": "InvalidExtraDataItem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "itemIndex", + "type": "uint256" + } + ], + "name": "InvalidExtraDataSortOrder", + "type": "error" + }, + { + "inputs": [], + "name": "LegacyOracleCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "LidoCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "LidoLocatorCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "NoConsensusReportToProcess", + "type": "error" + }, + { + "inputs": [], + "name": "NonZeroContractVersionOnInit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "ProcessingDeadlineMissed", + "type": "error" + }, + { + "inputs": [], + "name": "RefSlotAlreadyProcessing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "prevRefSlot", + "type": "uint256" + } + ], + "name": "RefSlotCannotDecrease", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingRefSlot", + "type": "uint256" + } + ], + "name": "RefSlotMustBeGreaterThanProcessingOne", + "type": "error" + }, + { + "inputs": [], + "name": "SecondsPerSlotCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "SenderIsNotTheConsensusContract", + "type": "error" + }, + { + "inputs": [], + "name": "SenderNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "UnexpectedChainConfig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedVersion", + "type": "uint256" + } + ], + "name": "UnexpectedConsensusVersion", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "UnexpectedContractVersion", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "consensusHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "receivedHash", + "type": "bytes32" + } + ], + "name": "UnexpectedDataHash", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedFormat", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedFormat", + "type": "uint256" + } + ], + "name": "UnexpectedExtraDataFormat", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "consensusHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "receivedHash", + "type": "bytes32" + } + ], + "name": "UnexpectedExtraDataHash", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedIndex", + "type": "uint256" + } + ], + "name": "UnexpectedExtraDataIndex", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedCount", + "type": "uint256" + } + ], + "name": "UnexpectedExtraDataItemsCount", + "type": "error" + }, + { + "inputs": [], + "name": "UnexpectedExtraDataLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "consensusRefSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dataRefSlot", + "type": "uint256" + } + ], + "name": "UnexpectedRefSlot", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "format", + "type": "uint256" + } + ], + "name": "UnsupportedExtraDataFormat", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "itemIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dataType", + "type": "uint256" + } + ], + "name": "UnsupportedExtraDataType", + "type": "error" + }, + { + "inputs": [], + "name": "VersionCannotBeSame", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "prevAddr", + "type": "address" + } + ], + "name": "ConsensusHashContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "prevVersion", + "type": "uint256" + } + ], + "name": "ConsensusVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + } + ], + "name": "ContractVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "itemsProcessed", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "itemsCount", + "type": "uint256" + } + ], + "name": "ExtraDataSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "ProcessingStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "ReportDiscarded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "processingDeadlineTime", + "type": "uint256" + } + ], + "name": "ReportSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "processedItemsCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "itemsCount", + "type": "uint256" + } + ], + "name": "WarnExtraDataIncompleteProcessing", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + } + ], + "name": "WarnProcessingMissed", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_DATA_FORMAT_EMPTY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_DATA_FORMAT_LIST", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_DATA_TYPE_EXITED_VALIDATORS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_DATA_TYPE_STUCK_VALIDATORS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GENESIS_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LEGACY_ORACLE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LIDO", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOCATOR", + "outputs": [ + { + "internalType": "contract ILidoLocator", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_CONSENSUS_CONTRACT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_CONSENSUS_VERSION_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SECONDS_PER_SLOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUBMIT_DATA_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + } + ], + "name": "discardConsensusReport", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + } + ], + "name": "finalizeUpgrade_v2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusReport", + "outputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingDeadlineTime", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "processingStarted", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastProcessingRefSlot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProcessingState", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "currentFrameRefSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingDeadlineTime", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "mainDataHash", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "mainDataSubmitted", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "extraDataHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "extraDataFormat", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "extraDataSubmitted", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "extraDataItemsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "extraDataItemsSubmitted", + "type": "uint256" + } + ], + "internalType": "struct AccountingOracle.ProcessingState", + "name": "result", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "consensusContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "consensusContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastProcessingRefSlot", + "type": "uint256" + } + ], + "name": "initializeWithoutMigration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "setConsensusContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "version", + "type": "uint256" + } + ], + "name": "setConsensusVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "reportHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "submitConsensusReport", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "clBalanceGwei", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "stakingModuleIdsWithNewlyExitedValidators", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "numExitedValidatorsByStakingModule", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "withdrawalVaultBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "elRewardsVaultBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sharesRequestedToBurn", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "withdrawalFinalizationBatches", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "simulatedShareRate", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isBunkerMode", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "extraDataFormat", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "extraDataHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "extraDataItemsCount", + "type": "uint256" + } + ], + "internalType": "struct AccountingOracle.ReportData", + "name": "data", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "contractVersion", + "type": "uint256" + } + ], + "name": "submitReportData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "submitReportExtraDataEmpty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "submitReportExtraDataList", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/interfaces/DepositSecurityModule.json b/interfaces/DepositSecurityModule.json index c02c8811b..fc5914fa3 100644 --- a/interfaces/DepositSecurityModule.json +++ b/interfaces/DepositSecurityModule.json @@ -1,74 +1,151 @@ [ { "inputs": [ - { "internalType": "address", "name": "_lido", "type": "address" }, { "internalType": "address", - "name": "_depositContract", + "name": "_lido", "type": "address" }, { "internalType": "address", - "name": "_stakingRouter", + "name": "_depositContract", "type": "address" }, { - "internalType": "uint256", - "name": "_maxDepositsPerBlock", - "type": "uint256" + "internalType": "address", + "name": "_stakingRouter", + "type": "address" }, { "internalType": "uint256", - "name": "_minDepositBlockDistance", + "name": "_pauseIntentValidityPeriodBlocks", "type": "uint256" }, { "internalType": "uint256", - "name": "_pauseIntentValidityPeriodBlocks", + "name": "_maxOperatorsPerUnvetting", "type": "uint256" } ], "stateMutability": "nonpayable", "type": "constructor" }, - { "inputs": [], "name": "DepositInactiveModule", "type": "error" }, - { "inputs": [], "name": "DepositNoQuorum", "type": "error" }, - { "inputs": [], "name": "DepositNonceChanged", "type": "error" }, - { "inputs": [], "name": "DepositRootChanged", "type": "error" }, - { "inputs": [], "name": "DepositTooFrequent", "type": "error" }, - { "inputs": [], "name": "DepositUnexpectedBlockHash", "type": "error" }, + { + "inputs": [], + "name": "DepositInactiveModule", + "type": "error" + }, + { + "inputs": [], + "name": "DepositNoQuorum", + "type": "error" + }, + { + "inputs": [], + "name": "DepositRootChanged", + "type": "error" + }, + { + "inputs": [], + "name": "DepositTooFrequent", + "type": "error" + }, + { + "inputs": [], + "name": "DepositUnexpectedBlockHash", + "type": "error" + }, + { + "inputs": [], + "name": "DepositsArePaused", + "type": "error" + }, + { + "inputs": [], + "name": "DepositsNotPaused", + "type": "error" + }, { "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" } + { + "internalType": "address", + "name": "addr", + "type": "address" + } ], "name": "DuplicateAddress", "type": "error" }, - { "inputs": [], "name": "InvalidSignature", "type": "error" }, + { + "inputs": [], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleNonceChanged", + "type": "error" + }, { "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" } + { + "internalType": "address", + "name": "addr", + "type": "address" + } ], "name": "NotAGuardian", "type": "error" }, { "inputs": [ - { "internalType": "address", "name": "caller", "type": "address" } + { + "internalType": "address", + "name": "caller", + "type": "address" + } ], "name": "NotAnOwner", "type": "error" }, - { "inputs": [], "name": "PauseIntentExpired", "type": "error" }, - { "inputs": [], "name": "SignaturesNotSorted", "type": "error" }, { - "inputs": [{ "internalType": "string", "name": "field", "type": "string" }], + "inputs": [], + "name": "PauseIntentExpired", + "type": "error" + }, + { + "inputs": [], + "name": "SignaturesNotSorted", + "type": "error" + }, + { + "inputs": [], + "name": "UnvetPayloadInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "UnvetUnexpectedBlockHash", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "field", + "type": "string" + } + ], "name": "ZeroAddress", "type": "error" }, { "inputs": [ - { "internalType": "string", "name": "parameter", "type": "string" } + { + "internalType": "string", + "name": "parameter", + "type": "string" + } ], "name": "ZeroParameter", "type": "error" @@ -81,12 +158,6 @@ "internalType": "address", "name": "guardian", "type": "address" - }, - { - "indexed": true, - "internalType": "uint24", - "name": "stakingModuleId", - "type": "uint24" } ], "name": "DepositsPaused", @@ -94,14 +165,7 @@ }, { "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint24", - "name": "stakingModuleId", - "type": "uint24" - } - ], + "inputs": [], "name": "DepositsUnpaused", "type": "event" }, @@ -154,7 +218,7 @@ "type": "uint256" } ], - "name": "MaxDepositsChanged", + "name": "LastDepositBlockChanged", "type": "event" }, { @@ -167,7 +231,7 @@ "type": "uint256" } ], - "name": "MinDepositBlockDistanceChanged", + "name": "MaxOperatorsPerUnvettingChanged", "type": "event" }, { @@ -199,7 +263,13 @@ { "inputs": [], "name": "ATTEST_MESSAGE_PREFIX", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], "stateMutability": "view", "type": "function" }, @@ -220,7 +290,11 @@ "inputs": [], "name": "LIDO", "outputs": [ - { "internalType": "contract ILido", "name": "", "type": "address" } + { + "internalType": "contract ILido", + "name": "", + "type": "address" + } ], "stateMutability": "view", "type": "function" @@ -228,7 +302,13 @@ { "inputs": [], "name": "PAUSE_MESSAGE_PREFIX", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], "stateMutability": "view", "type": "function" }, @@ -245,10 +325,44 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "UNVET_MESSAGE_PREFIX", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" }, - { "internalType": "uint256", "name": "newQuorum", "type": "uint256" } + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newQuorum", + "type": "uint256" + } ], "name": "addGuardian", "outputs": [], @@ -257,8 +371,16 @@ }, { "inputs": [ - { "internalType": "address[]", "name": "addresses", "type": "address[]" }, - { "internalType": "uint256", "name": "newQuorum", "type": "uint256" } + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "newQuorum", + "type": "uint256" + } ], "name": "addGuardians", "outputs": [], @@ -274,26 +396,60 @@ } ], "name": "canDeposit", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [ - { "internalType": "uint256", "name": "blockNumber", "type": "uint256" }, - { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" }, - { "internalType": "bytes32", "name": "depositRoot", "type": "bytes32" }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "depositRoot", + "type": "bytes32" + }, { "internalType": "uint256", "name": "stakingModuleId", "type": "uint256" }, - { "internalType": "uint256", "name": "nonce", "type": "uint256" }, - { "internalType": "bytes", "name": "depositCalldata", "type": "bytes" }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "depositCalldata", + "type": "bytes" + }, { "components": [ - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "vs", "type": "bytes32" } + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "vs", + "type": "bytes32" + } ], "internalType": "struct DepositSecurityModule.Signature[]", "name": "sortedGuardianSignatures", @@ -307,17 +463,33 @@ }, { "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" } + { + "internalType": "address", + "name": "addr", + "type": "address" + } ], "name": "getGuardianIndex", - "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getGuardianQuorum", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], "stateMutability": "view", "type": "function" }, @@ -325,60 +497,137 @@ "inputs": [], "name": "getGuardians", "outputs": [ - { "internalType": "address[]", "name": "", "type": "address[]" } + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } ], "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "getMaxDeposits", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "getLastDepositBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "getMinDepositBlockDistance", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "getMaxOperatorsPerUnvetting", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getOwner", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getPauseIntentValidityPeriodBlocks", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isDepositsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" } + { + "internalType": "address", + "name": "addr", + "type": "address" + } ], "name": "isGuardian", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], "stateMutability": "view", "type": "function" }, { "inputs": [ - { "internalType": "uint256", "name": "blockNumber", "type": "uint256" }, { "internalType": "uint256", "name": "stakingModuleId", "type": "uint256" + } + ], + "name": "isMinDepositDistancePassed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" }, { "components": [ - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "vs", "type": "bytes32" } + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "vs", + "type": "bytes32" + } ], "internalType": "struct DepositSecurityModule.Signature", "name": "sig", @@ -392,8 +641,16 @@ }, { "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" }, - { "internalType": "uint256", "name": "newQuorum", "type": "uint256" } + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newQuorum", + "type": "uint256" + } ], "name": "removeGuardian", "outputs": [], @@ -402,7 +659,11 @@ }, { "inputs": [ - { "internalType": "uint256", "name": "newValue", "type": "uint256" } + { + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } ], "name": "setGuardianQuorum", "outputs": [], @@ -411,49 +672,101 @@ }, { "inputs": [ - { "internalType": "uint256", "name": "newValue", "type": "uint256" } + { + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } ], - "name": "setMaxDeposits", + "name": "setMaxOperatorsPerUnvetting", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { "internalType": "uint256", "name": "newValue", "type": "uint256" } + { + "internalType": "address", + "name": "newValue", + "type": "address" + } ], - "name": "setMinDepositBlockDistance", + "name": "setOwner", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { "internalType": "address", "name": "newValue", "type": "address" } + { + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } ], - "name": "setOwner", + "name": "setPauseIntentValidityPeriodBlocks", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { "internalType": "uint256", "name": "newValue", "type": "uint256" } - ], - "name": "setPauseIntentValidityPeriodBlocks", + "inputs": [], + "name": "unpauseDeposits", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, { "internalType": "uint256", "name": "stakingModuleId", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "nodeOperatorIds", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "vettedSigningKeysCounts", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "vs", + "type": "bytes32" + } + ], + "internalType": "struct DepositSecurityModule.Signature", + "name": "sig", + "type": "tuple" } ], - "name": "unpauseDeposits", + "name": "unvetSigningKeys", "outputs": [], "stateMutability": "nonpayable", "type": "function" diff --git a/interfaces/NodeOperatorsRegistry.json b/interfaces/NodeOperatorsRegistry.json index 2e8914d97..bbff81661 100644 --- a/interfaces/NodeOperatorsRegistry.json +++ b/interfaces/NodeOperatorsRegistry.json @@ -1,1634 +1,1634 @@ [ - { - "constant": true, - "inputs": [], - "name": "hasInitialized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_targetLimitMode", - "type": "uint256" - }, - { - "name": "_targetLimit", - "type": "uint256" - } - ], - "name": "updateTargetValidatorsLimits", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_keysCount", - "type": "uint256" - }, - { - "name": "_publicKeys", - "type": "bytes" - }, - { - "name": "_signatures", - "type": "bytes" - } - ], - "name": "addSigningKeys", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getType", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_script", - "type": "bytes" - } - ], - "name": "getEVMScriptExecutor", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "clearNodeOperatorPenalty", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getRecoveryVault", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_offset", - "type": "uint256" - }, - { - "name": "_limit", - "type": "uint256" - } - ], - "name": "getNodeOperatorIds", - "outputs": [ - { - "name": "nodeOperatorIds", - "type": "uint256[]" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_offset", - "type": "uint256" - }, - { - "name": "_limit", - "type": "uint256" - } - ], - "name": "getSigningKeys", - "outputs": [ - { - "name": "pubkeys", - "type": "bytes" - }, - { - "name": "signatures", - "type": "bytes" - }, - { - "name": "used", - "type": "bool[]" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_fromIndex", - "type": "uint256" - }, - { - "name": "_keysCount", - "type": "uint256" - } - ], - "name": "removeSigningKeysOperatorBH", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "getNodeOperatorIsActive", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_name", - "type": "string" - } - ], - "name": "setNodeOperatorName", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_totalRewardShares", - "type": "uint256" - } - ], - "name": "getRewardsDistribution", - "outputs": [ - { - "name": "recipients", - "type": "address[]" - }, - { - "name": "shares", - "type": "uint256[]" - }, - { - "name": "penalized", - "type": "bool[]" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_indexFrom", - "type": "uint256" - }, - { - "name": "_indexTo", - "type": "uint256" - } - ], - "name": "invalidateReadyToDepositKeysRange", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_locator", - "type": "address" - }, - { - "name": "_type", - "type": "bytes32" - }, - { - "name": "_stuckPenaltyDelay", - "type": "uint256" - } - ], - "name": "initialize", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_delay", - "type": "uint256" - } - ], - "name": "setStuckPenaltyDelay", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "finalizeUpgrade_v3", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getStuckPenaltyDelay", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_index", - "type": "uint256" - } - ], - "name": "removeSigningKey", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getRewardDistributionState", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_fromIndex", - "type": "uint256" - }, - { - "name": "_keysCount", - "type": "uint256" - } - ], - "name": "removeSigningKeys", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "isOperatorPenalized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "deactivateNodeOperator", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "token", - "type": "address" - } - ], - "name": "allowRecoverability", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "STAKING_ROUTER_ROLE", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_keysCount", - "type": "uint256" - }, - { - "name": "_publicKeys", - "type": "bytes" - }, - { - "name": "_signatures", - "type": "bytes" - } - ], - "name": "addSigningKeysOperatorBH", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "appId", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getActiveNodeOperatorsCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_name", - "type": "string" - }, - { - "name": "_rewardAddress", - "type": "address" - } - ], - "name": "addNodeOperator", - "outputs": [ - { - "name": "id", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getContractVersion", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getInitializationBlock", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "getUnusedSigningKeyCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "onRewardsMinted", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MANAGE_NODE_OPERATOR_ROLE", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "distributeReward", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "onWithdrawalCredentialsChanged", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "activateNodeOperator", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_rewardAddress", - "type": "address" - } - ], - "name": "setNodeOperatorRewardAddress", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_fullInfo", - "type": "bool" - } - ], - "name": "getNodeOperator", - "outputs": [ - { - "name": "active", - "type": "bool" - }, - { - "name": "name", - "type": "string" - }, - { - "name": "rewardAddress", - "type": "address" - }, - { - "name": "totalVettedValidators", - "type": "uint64" - }, - { - "name": "totalExitedValidators", - "type": "uint64" - }, - { - "name": "totalAddedValidators", - "type": "uint64" - }, - { - "name": "totalDepositedValidators", - "type": "uint64" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_locator", - "type": "address" - }, - { - "name": "_type", - "type": "bytes32" - }, - { - "name": "_stuckPenaltyDelay", - "type": "uint256" - } - ], - "name": "finalizeUpgrade_v2", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getStakingModuleSummary", - "outputs": [ - { - "name": "totalExitedValidators", - "type": "uint256" - }, - { - "name": "totalDepositedValidators", - "type": "uint256" - }, - { - "name": "depositableValidatorsCount", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorIds", - "type": "bytes" - }, - { - "name": "_exitedValidatorsCounts", - "type": "bytes" - } - ], - "name": "updateExitedValidatorsCount", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorIds", - "type": "bytes" - }, - { - "name": "_stuckValidatorsCounts", - "type": "bytes" - } - ], - "name": "updateStuckValidatorsCount", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - } - ], - "name": "transferToVault", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_sender", - "type": "address" - }, - { - "name": "_role", - "type": "bytes32" - }, - { - "name": "_params", - "type": "uint256[]" - } - ], - "name": "canPerform", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_refundedValidatorsCount", - "type": "uint256" - } - ], - "name": "updateRefundedValidatorsCount", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getEVMScriptRegistry", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getNodeOperatorsCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_vettedSigningKeysCount", - "type": "uint64" - } - ], - "name": "setNodeOperatorStakingLimit", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "getNodeOperatorSummary", - "outputs": [ - { - "name": "targetLimitMode", - "type": "uint256" - }, - { - "name": "targetValidatorsCount", - "type": "uint256" - }, - { - "name": "stuckValidatorsCount", - "type": "uint256" - }, - { - "name": "refundedValidatorsCount", - "type": "uint256" - }, - { - "name": "stuckPenaltyEndTimestamp", - "type": "uint256" - }, - { - "name": "totalExitedValidators", - "type": "uint256" - }, - { - "name": "totalDepositedValidators", - "type": "uint256" - }, - { - "name": "depositableValidatorsCount", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_index", - "type": "uint256" - } - ], - "name": "getSigningKey", - "outputs": [ - { - "name": "key", - "type": "bytes" - }, - { - "name": "depositSignature", - "type": "bytes" - }, - { - "name": "used", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_NODE_OPERATOR_NAME_LENGTH", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorIds", - "type": "bytes" - }, - { - "name": "_vettedSigningKeysCounts", - "type": "bytes" - } - ], - "name": "decreaseVettedSigningKeysCount", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_depositsCount", - "type": "uint256" - }, - { - "name": "", - "type": "bytes" - } - ], - "name": "obtainDepositData", - "outputs": [ - { - "name": "publicKeys", - "type": "bytes" - }, - { - "name": "signatures", - "type": "bytes" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getKeysOpIndex", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getNonce", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "kernel", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getLocator", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "SET_NODE_OPERATOR_LIMIT_ROLE", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "getTotalSigningKeyCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "isPetrified", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_STUCK_PENALTY_DELAY", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "onExitedAndStuckValidatorsCountsUpdated", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_NODE_OPERATORS_COUNT", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_index", - "type": "uint256" - } - ], - "name": "removeSigningKeyOperatorBH", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - }, - { - "name": "_exitedValidatorsCount", - "type": "uint256" - }, - { - "name": "_stuckValidatorsCount", - "type": "uint256" - } - ], - "name": "unsafeUpdateValidatorsCount", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MANAGE_SIGNING_KEYS", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_nodeOperatorId", - "type": "uint256" - } - ], - "name": "isOperatorPenaltyCleared", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "rewardAddress", - "type": "address" - }, - { - "indexed": false, - "name": "stakingLimit", - "type": "uint64" - } - ], - "name": "NodeOperatorAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "active", - "type": "bool" - } - ], - "name": "NodeOperatorActiveSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "name", - "type": "string" - } - ], - "name": "NodeOperatorNameSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "rewardAddress", - "type": "address" - } - ], - "name": "NodeOperatorRewardAddressSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "totalKeysTrimmed", - "type": "uint64" - } - ], - "name": "NodeOperatorTotalKeysTrimmed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "keysOpIndex", - "type": "uint256" - } - ], - "name": "KeysOpIndexSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "moduleType", - "type": "bytes32" - } - ], - "name": "StakingModuleTypeSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "rewardAddress", - "type": "address" - }, - { - "indexed": false, - "name": "sharesAmount", - "type": "uint256" - } - ], - "name": "RewardsDistributed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "state", - "type": "uint8" - } - ], - "name": "RewardDistributionStateChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "locatorAddress", - "type": "address" - } - ], - "name": "LocatorContractSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "approvedValidatorsCount", - "type": "uint256" - } - ], - "name": "VettedSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "depositedValidatorsCount", - "type": "uint256" - } - ], - "name": "DepositedSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "exitedValidatorsCount", - "type": "uint256" - } - ], - "name": "ExitedSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "totalValidatorsCount", - "type": "uint256" - } - ], - "name": "TotalSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "nonce", - "type": "uint256" - } - ], - "name": "NonceChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "stuckPenaltyDelay", - "type": "uint256" - } - ], - "name": "StuckPenaltyDelayChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "stuckValidatorsCount", - "type": "uint256" - }, - { - "indexed": false, - "name": "refundedValidatorsCount", - "type": "uint256" - }, - { - "indexed": false, - "name": "stuckPenaltyEndTimestamp", - "type": "uint256" - } - ], - "name": "StuckPenaltyStateChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "name": "targetValidatorsCount", - "type": "uint256" - }, - { - "indexed": false, - "name": "targetLimitMode", - "type": "uint256" - } - ], - "name": "TargetValidatorsCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "recipientAddress", - "type": "address" - }, - { - "indexed": false, - "name": "sharesPenalizedAmount", - "type": "uint256" - } - ], - "name": "NodeOperatorPenalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "version", - "type": "uint256" - } - ], - "name": "ContractVersionSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "executor", - "type": "address" - }, - { - "indexed": false, - "name": "script", - "type": "bytes" - }, - { - "indexed": false, - "name": "input", - "type": "bytes" - }, - { - "indexed": false, - "name": "returnData", - "type": "bytes" - } - ], - "name": "ScriptResult", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "vault", - "type": "address" - }, - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "RecoverToVault", - "type": "event" - } - ] \ No newline at end of file + { + "constant": true, + "inputs": [], + "name": "hasInitialized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_targetLimitMode", + "type": "uint256" + }, + { + "name": "_targetLimit", + "type": "uint256" + } + ], + "name": "updateTargetValidatorsLimits", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + }, + { + "name": "_publicKeys", + "type": "bytes" + }, + { + "name": "_signatures", + "type": "bytes" + } + ], + "name": "addSigningKeys", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getType", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_script", + "type": "bytes" + } + ], + "name": "getEVMScriptExecutor", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "clearNodeOperatorPenalty", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getRecoveryVault", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_limit", + "type": "uint256" + } + ], + "name": "getNodeOperatorIds", + "outputs": [ + { + "name": "nodeOperatorIds", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_limit", + "type": "uint256" + } + ], + "name": "getSigningKeys", + "outputs": [ + { + "name": "pubkeys", + "type": "bytes" + }, + { + "name": "signatures", + "type": "bytes" + }, + { + "name": "used", + "type": "bool[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fromIndex", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + } + ], + "name": "removeSigningKeysOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getNodeOperatorIsActive", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_name", + "type": "string" + } + ], + "name": "setNodeOperatorName", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_totalRewardShares", + "type": "uint256" + } + ], + "name": "getRewardsDistribution", + "outputs": [ + { + "name": "recipients", + "type": "address[]" + }, + { + "name": "shares", + "type": "uint256[]" + }, + { + "name": "penalized", + "type": "bool[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_indexFrom", + "type": "uint256" + }, + { + "name": "_indexTo", + "type": "uint256" + } + ], + "name": "invalidateReadyToDepositKeysRange", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_locator", + "type": "address" + }, + { + "name": "_type", + "type": "bytes32" + }, + { + "name": "_stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_delay", + "type": "uint256" + } + ], + "name": "setStuckPenaltyDelay", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "finalizeUpgrade_v3", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getStuckPenaltyDelay", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "removeSigningKey", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getRewardDistributionState", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fromIndex", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + } + ], + "name": "removeSigningKeys", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "isOperatorPenalized", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "deactivateNodeOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "token", + "type": "address" + } + ], + "name": "allowRecoverability", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "STAKING_ROUTER_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_keysCount", + "type": "uint256" + }, + { + "name": "_publicKeys", + "type": "bytes" + }, + { + "name": "_signatures", + "type": "bytes" + } + ], + "name": "addSigningKeysOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "appId", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getActiveNodeOperatorsCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "_rewardAddress", + "type": "address" + } + ], + "name": "addNodeOperator", + "outputs": [ + { + "name": "id", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getInitializationBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getUnusedSigningKeyCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "onRewardsMinted", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MANAGE_NODE_OPERATOR_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "distributeReward", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "onWithdrawalCredentialsChanged", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "activateNodeOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_rewardAddress", + "type": "address" + } + ], + "name": "setNodeOperatorRewardAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_fullInfo", + "type": "bool" + } + ], + "name": "getNodeOperator", + "outputs": [ + { + "name": "active", + "type": "bool" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "rewardAddress", + "type": "address" + }, + { + "name": "totalVettedValidators", + "type": "uint64" + }, + { + "name": "totalExitedValidators", + "type": "uint64" + }, + { + "name": "totalAddedValidators", + "type": "uint64" + }, + { + "name": "totalDepositedValidators", + "type": "uint64" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_locator", + "type": "address" + }, + { + "name": "_type", + "type": "bytes32" + }, + { + "name": "_stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "finalizeUpgrade_v2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getStakingModuleSummary", + "outputs": [ + { + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_exitedValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateExitedValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_stuckValidatorsCounts", + "type": "bytes" + } + ], + "name": "updateStuckValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_token", + "type": "address" + } + ], + "name": "transferToVault", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_sender", + "type": "address" + }, + { + "name": "_role", + "type": "bytes32" + }, + { + "name": "_params", + "type": "uint256[]" + } + ], + "name": "canPerform", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_refundedValidatorsCount", + "type": "uint256" + } + ], + "name": "updateRefundedValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getEVMScriptRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getNodeOperatorsCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_vettedSigningKeysCount", + "type": "uint64" + } + ], + "name": "setNodeOperatorStakingLimit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getNodeOperatorSummary", + "outputs": [ + { + "name": "targetLimitMode", + "type": "uint256" + }, + { + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + }, + { + "name": "totalExitedValidators", + "type": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "getSigningKey", + "outputs": [ + { + "name": "key", + "type": "bytes" + }, + { + "name": "depositSignature", + "type": "bytes" + }, + { + "name": "used", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_NODE_OPERATOR_NAME_LENGTH", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorIds", + "type": "bytes" + }, + { + "name": "_vettedSigningKeysCounts", + "type": "bytes" + } + ], + "name": "decreaseVettedSigningKeysCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_depositsCount", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "obtainDepositData", + "outputs": [ + { + "name": "publicKeys", + "type": "bytes" + }, + { + "name": "signatures", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getKeysOpIndex", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getNonce", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kernel", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getLocator", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "SET_NODE_OPERATOR_LIMIT_ROLE", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "getTotalSigningKeyCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isPetrified", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_STUCK_PENALTY_DELAY", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "onExitedAndStuckValidatorsCountsUpdated", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_NODE_OPERATORS_COUNT", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_index", + "type": "uint256" + } + ], + "name": "removeSigningKeyOperatorBH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_exitedValidatorsCount", + "type": "uint256" + }, + { + "name": "_stuckValidatorsCount", + "type": "uint256" + } + ], + "name": "unsafeUpdateValidatorsCount", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MANAGE_SIGNING_KEYS", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + } + ], + "name": "isOperatorPenaltyCleared", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "name", + "type": "string" + }, + { + "indexed": false, + "name": "rewardAddress", + "type": "address" + }, + { + "indexed": false, + "name": "stakingLimit", + "type": "uint64" + } + ], + "name": "NodeOperatorAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "active", + "type": "bool" + } + ], + "name": "NodeOperatorActiveSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "name", + "type": "string" + } + ], + "name": "NodeOperatorNameSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "rewardAddress", + "type": "address" + } + ], + "name": "NodeOperatorRewardAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalKeysTrimmed", + "type": "uint64" + } + ], + "name": "NodeOperatorTotalKeysTrimmed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "keysOpIndex", + "type": "uint256" + } + ], + "name": "KeysOpIndexSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "moduleType", + "type": "bytes32" + } + ], + "name": "StakingModuleTypeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "rewardAddress", + "type": "address" + }, + { + "indexed": false, + "name": "sharesAmount", + "type": "uint256" + } + ], + "name": "RewardsDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "state", + "type": "uint8" + } + ], + "name": "RewardDistributionStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "locatorAddress", + "type": "address" + } + ], + "name": "LocatorContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "approvedValidatorsCount", + "type": "uint256" + } + ], + "name": "VettedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "depositedValidatorsCount", + "type": "uint256" + } + ], + "name": "DepositedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "exitedValidatorsCount", + "type": "uint256" + } + ], + "name": "ExitedSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalValidatorsCount", + "type": "uint256" + } + ], + "name": "TotalSigningKeysCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "nonce", + "type": "uint256" + } + ], + "name": "NonceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "stuckPenaltyDelay", + "type": "uint256" + } + ], + "name": "StuckPenaltyDelayChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "stuckValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "refundedValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "stuckPenaltyEndTimestamp", + "type": "uint256" + } + ], + "name": "StuckPenaltyStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "nodeOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "name": "targetValidatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "name": "targetLimitMode", + "type": "uint256" + } + ], + "name": "TargetValidatorsCountChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "recipientAddress", + "type": "address" + }, + { + "indexed": false, + "name": "sharesPenalizedAmount", + "type": "uint256" + } + ], + "name": "NodeOperatorPenalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "version", + "type": "uint256" + } + ], + "name": "ContractVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "executor", + "type": "address" + }, + { + "indexed": false, + "name": "script", + "type": "bytes" + }, + { + "indexed": false, + "name": "input", + "type": "bytes" + }, + { + "indexed": false, + "name": "returnData", + "type": "bytes" + } + ], + "name": "ScriptResult", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "vault", + "type": "address" + }, + { + "indexed": true, + "name": "token", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "RecoverToVault", + "type": "event" + } +] diff --git a/interfaces/OracleReportSanityChecker.json b/interfaces/OracleReportSanityChecker.json index f2932b2c6..6c50e9878 100644 --- a/interfaces/OracleReportSanityChecker.json +++ b/interfaces/OracleReportSanityChecker.json @@ -1 +1,1382 @@ -[{"inputs":[{"internalType":"address","name":"_lidoLocator","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"components":[{"internalType":"uint256","name":"churnValidatorsPerDayLimit","type":"uint256"},{"internalType":"uint256","name":"oneOffCLBalanceDecreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"annualBalanceIncreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"simulatedShareRateDeviationBPLimit","type":"uint256"},{"internalType":"uint256","name":"maxValidatorExitRequestsPerReport","type":"uint256"},{"internalType":"uint256","name":"maxAccountingExtraDataListItemsCount","type":"uint256"},{"internalType":"uint256","name":"maxNodeOperatorsPerExtraDataItemCount","type":"uint256"},{"internalType":"uint256","name":"requestTimestampMargin","type":"uint256"},{"internalType":"uint256","name":"maxPositiveTokenRebase","type":"uint256"}],"internalType":"struct LimitsList","name":"_limitsList","type":"tuple"},{"components":[{"internalType":"address[]","name":"allLimitsManagers","type":"address[]"},{"internalType":"address[]","name":"churnValidatorsPerDayLimitManagers","type":"address[]"},{"internalType":"address[]","name":"oneOffCLBalanceDecreaseLimitManagers","type":"address[]"},{"internalType":"address[]","name":"annualBalanceIncreaseLimitManagers","type":"address[]"},{"internalType":"address[]","name":"shareRateDeviationLimitManagers","type":"address[]"},{"internalType":"address[]","name":"maxValidatorExitRequestsPerReportManagers","type":"address[]"},{"internalType":"address[]","name":"maxAccountingExtraDataListItemsCountManagers","type":"address[]"},{"internalType":"address[]","name":"maxNodeOperatorsPerExtraDataItemCountManagers","type":"address[]"},{"internalType":"address[]","name":"requestTimestampMarginManagers","type":"address[]"},{"internalType":"address[]","name":"maxPositiveTokenRebaseManagers","type":"address[]"}],"internalType":"struct OracleReportSanityChecker.ManagersRoster","name":"_managersRoster","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ActualShareRateIsZero","type":"error"},{"inputs":[],"name":"AdminCannotBeZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"limitPerDay","type":"uint256"},{"internalType":"uint256","name":"exitedPerDay","type":"uint256"}],"name":"ExitedValidatorsLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint256","name":"churnLimit","type":"uint256"}],"name":"IncorrectAppearedValidators","type":"error"},{"inputs":[{"internalType":"uint256","name":"oneOffCLBalanceDecreaseBP","type":"uint256"}],"name":"IncorrectCLBalanceDecrease","type":"error"},{"inputs":[{"internalType":"uint256","name":"annualBalanceDiff","type":"uint256"}],"name":"IncorrectCLBalanceIncrease","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualELRewardsVaultBalance","type":"uint256"}],"name":"IncorrectELRewardsVaultBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"churnLimit","type":"uint256"}],"name":"IncorrectExitedValidators","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"minAllowedValue","type":"uint256"},{"internalType":"uint256","name":"maxAllowedValue","type":"uint256"}],"name":"IncorrectLimitValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxRequestsCount","type":"uint256"}],"name":"IncorrectNumberOfExitRequestsPerReport","type":"error"},{"inputs":[{"internalType":"uint256","name":"requestCreationBlock","type":"uint256"}],"name":"IncorrectRequestFinalization","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualSharesToBurn","type":"uint256"}],"name":"IncorrectSharesRequestedToBurn","type":"error"},{"inputs":[{"internalType":"uint256","name":"simulatedShareRate","type":"uint256"},{"internalType":"uint256","name":"actualShareRate","type":"uint256"}],"name":"IncorrectSimulatedShareRate","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualWithdrawalVaultBalance","type":"uint256"}],"name":"IncorrectWithdrawalsVaultBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxItemsCount","type":"uint256"},{"internalType":"uint256","name":"receivedItemsCount","type":"uint256"}],"name":"MaxAccountingExtraDataItemsCountExceeded","type":"error"},{"inputs":[],"name":"NegativeTotalPooledEther","type":"error"},{"inputs":[],"name":"TooHighTokenRebaseLimit","type":"error"},{"inputs":[],"name":"TooLowTokenRebaseLimit","type":"error"},{"inputs":[{"internalType":"uint256","name":"itemIndex","type":"uint256"},{"internalType":"uint256","name":"nodeOpsCount","type":"uint256"}],"name":"TooManyNodeOpsPerExtraDataItem","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"annualBalanceIncreaseBPLimit","type":"uint256"}],"name":"AnnualBalanceIncreaseBPLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"churnValidatorsPerDayLimit","type":"uint256"}],"name":"ChurnValidatorsPerDayLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxAccountingExtraDataListItemsCount","type":"uint256"}],"name":"MaxAccountingExtraDataListItemsCountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxNodeOperatorsPerExtraDataItemCount","type":"uint256"}],"name":"MaxNodeOperatorsPerExtraDataItemCountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxPositiveTokenRebase","type":"uint256"}],"name":"MaxPositiveTokenRebaseSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxValidatorExitRequestsPerReport","type":"uint256"}],"name":"MaxValidatorExitRequestsPerReportSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oneOffCLBalanceDecreaseBPLimit","type":"uint256"}],"name":"OneOffCLBalanceDecreaseBPLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestTimestampMargin","type":"uint256"}],"name":"RequestTimestampMarginSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"simulatedShareRateDeviationBPLimit","type":"uint256"}],"name":"SimulatedShareRateDeviationBPLimitSet","type":"event"},{"inputs":[],"name":"ALL_LIMITS_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHURN_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_POSITIVE_TOKEN_REBASE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_extraDataListItemsCount","type":"uint256"}],"name":"checkAccountingExtraDataListItemsCount","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timeElapsed","type":"uint256"},{"internalType":"uint256","name":"_preCLBalance","type":"uint256"},{"internalType":"uint256","name":"_postCLBalance","type":"uint256"},{"internalType":"uint256","name":"_withdrawalVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_elRewardsVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_sharesRequestedToBurn","type":"uint256"},{"internalType":"uint256","name":"_preCLValidators","type":"uint256"},{"internalType":"uint256","name":"_postCLValidators","type":"uint256"}],"name":"checkAccountingOracleReport","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_exitRequestsCount","type":"uint256"}],"name":"checkExitBusOracleReport","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_exitedValidatorsCount","type":"uint256"}],"name":"checkExitedValidatorsRatePerDay","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_itemIndex","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorsCount","type":"uint256"}],"name":"checkNodeOperatorsPerExtraDataItemCount","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_postTotalPooledEther","type":"uint256"},{"internalType":"uint256","name":"_postTotalShares","type":"uint256"},{"internalType":"uint256","name":"_etherLockedOnWithdrawalQueue","type":"uint256"},{"internalType":"uint256","name":"_sharesBurntDueToWithdrawals","type":"uint256"},{"internalType":"uint256","name":"_simulatedShareRate","type":"uint256"}],"name":"checkSimulatedShareRate","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastFinalizableRequestId","type":"uint256"},{"internalType":"uint256","name":"_reportTimestamp","type":"uint256"}],"name":"checkWithdrawalQueueOracleReport","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLidoLocator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxPositiveTokenRebase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracleReportLimits","outputs":[{"components":[{"internalType":"uint256","name":"churnValidatorsPerDayLimit","type":"uint256"},{"internalType":"uint256","name":"oneOffCLBalanceDecreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"annualBalanceIncreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"simulatedShareRateDeviationBPLimit","type":"uint256"},{"internalType":"uint256","name":"maxValidatorExitRequestsPerReport","type":"uint256"},{"internalType":"uint256","name":"maxAccountingExtraDataListItemsCount","type":"uint256"},{"internalType":"uint256","name":"maxNodeOperatorsPerExtraDataItemCount","type":"uint256"},{"internalType":"uint256","name":"requestTimestampMargin","type":"uint256"},{"internalType":"uint256","name":"maxPositiveTokenRebase","type":"uint256"}],"internalType":"struct LimitsList","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_annualBalanceIncreaseBPLimit","type":"uint256"}],"name":"setAnnualBalanceIncreaseBPLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_churnValidatorsPerDayLimit","type":"uint256"}],"name":"setChurnValidatorsPerDayLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxAccountingExtraDataListItemsCount","type":"uint256"}],"name":"setMaxAccountingExtraDataListItemsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValidatorExitRequestsPerReport","type":"uint256"}],"name":"setMaxExitRequestsPerOracleReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxNodeOperatorsPerExtraDataItemCount","type":"uint256"}],"name":"setMaxNodeOperatorsPerExtraDataItemCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxPositiveTokenRebase","type":"uint256"}],"name":"setMaxPositiveTokenRebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_oneOffCLBalanceDecreaseBPLimit","type":"uint256"}],"name":"setOneOffCLBalanceDecreaseBPLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"churnValidatorsPerDayLimit","type":"uint256"},{"internalType":"uint256","name":"oneOffCLBalanceDecreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"annualBalanceIncreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"simulatedShareRateDeviationBPLimit","type":"uint256"},{"internalType":"uint256","name":"maxValidatorExitRequestsPerReport","type":"uint256"},{"internalType":"uint256","name":"maxAccountingExtraDataListItemsCount","type":"uint256"},{"internalType":"uint256","name":"maxNodeOperatorsPerExtraDataItemCount","type":"uint256"},{"internalType":"uint256","name":"requestTimestampMargin","type":"uint256"},{"internalType":"uint256","name":"maxPositiveTokenRebase","type":"uint256"}],"internalType":"struct LimitsList","name":"_limitsList","type":"tuple"}],"name":"setOracleReportLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestTimestampMargin","type":"uint256"}],"name":"setRequestTimestampMargin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_simulatedShareRateDeviationBPLimit","type":"uint256"}],"name":"setSimulatedShareRateDeviationBPLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_preTotalPooledEther","type":"uint256"},{"internalType":"uint256","name":"_preTotalShares","type":"uint256"},{"internalType":"uint256","name":"_preCLBalance","type":"uint256"},{"internalType":"uint256","name":"_postCLBalance","type":"uint256"},{"internalType":"uint256","name":"_withdrawalVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_elRewardsVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_sharesRequestedToBurn","type":"uint256"},{"internalType":"uint256","name":"_etherToLockForWithdrawals","type":"uint256"},{"internalType":"uint256","name":"_newSharesToBurnForWithdrawals","type":"uint256"}],"name":"smoothenTokenRebase","outputs":[{"internalType":"uint256","name":"withdrawals","type":"uint256"},{"internalType":"uint256","name":"elRewards","type":"uint256"},{"internalType":"uint256","name":"simulatedSharesToBurn","type":"uint256"},{"internalType":"uint256","name":"sharesToBurn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_lidoLocator", + "type": "address" + }, + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "exitedValidatorsPerDayLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "oneOffCLBalanceDecreaseBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "annualBalanceIncreaseBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "simulatedShareRateDeviationBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxValidatorExitRequestsPerReport", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxAccountingExtraDataListItemsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxNodeOperatorsPerExtraDataItemCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestTimestampMargin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPositiveTokenRebase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "appearedValidatorsPerDayLimit", + "type": "uint256" + } + ], + "internalType": "struct LimitsList", + "name": "_limitsList", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address[]", + "name": "allLimitsManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "exitedValidatorsPerDayLimitManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "appearedValidatorsPerDayLimitManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "oneOffCLBalanceDecreaseLimitManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "annualBalanceIncreaseLimitManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "shareRateDeviationLimitManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "maxValidatorExitRequestsPerReportManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "maxAccountingExtraDataListItemsCountManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "maxNodeOperatorsPerExtraDataItemCountManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "requestTimestampMarginManagers", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "maxPositiveTokenRebaseManagers", + "type": "address[]" + } + ], + "internalType": "struct OracleReportSanityChecker.ManagersRoster", + "name": "_managersRoster", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ActualShareRateIsZero", + "type": "error" + }, + { + "inputs": [], + "name": "AdminCannotBeZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limitPerDay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exitedPerDay", + "type": "uint256" + } + ], + "name": "ExitedValidatorsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "appearedValidatorsLimit", + "type": "uint256" + } + ], + "name": "IncorrectAppearedValidators", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "oneOffCLBalanceDecreaseBP", + "type": "uint256" + } + ], + "name": "IncorrectCLBalanceDecrease", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "annualBalanceDiff", + "type": "uint256" + } + ], + "name": "IncorrectCLBalanceIncrease", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "actualELRewardsVaultBalance", + "type": "uint256" + } + ], + "name": "IncorrectELRewardsVaultBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "exitedValudatorsLimit", + "type": "uint256" + } + ], + "name": "IncorrectExitedValidators", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minAllowedValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxAllowedValue", + "type": "uint256" + } + ], + "name": "IncorrectLimitValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxRequestsCount", + "type": "uint256" + } + ], + "name": "IncorrectNumberOfExitRequestsPerReport", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requestCreationBlock", + "type": "uint256" + } + ], + "name": "IncorrectRequestFinalization", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "actualSharesToBurn", + "type": "uint256" + } + ], + "name": "IncorrectSharesRequestedToBurn", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "simulatedShareRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualShareRate", + "type": "uint256" + } + ], + "name": "IncorrectSimulatedShareRate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "actualWithdrawalVaultBalance", + "type": "uint256" + } + ], + "name": "IncorrectWithdrawalsVaultBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxItemsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedItemsCount", + "type": "uint256" + } + ], + "name": "MaxAccountingExtraDataItemsCountExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "NegativeTotalPooledEther", + "type": "error" + }, + { + "inputs": [], + "name": "TooHighTokenRebaseLimit", + "type": "error" + }, + { + "inputs": [], + "name": "TooLowTokenRebaseLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "itemIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nodeOpsCount", + "type": "uint256" + } + ], + "name": "TooManyNodeOpsPerExtraDataItem", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "annualBalanceIncreaseBPLimit", + "type": "uint256" + } + ], + "name": "AnnualBalanceIncreaseBPLimitSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "appearedValidatorsPerDayLimit", + "type": "uint256" + } + ], + "name": "AppearedValidatorsPerDayLimitSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "exitedValidatorsPerDayLimit", + "type": "uint256" + } + ], + "name": "ExitedValidatorsPerDayLimitSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxAccountingExtraDataListItemsCount", + "type": "uint256" + } + ], + "name": "MaxAccountingExtraDataListItemsCountSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxNodeOperatorsPerExtraDataItemCount", + "type": "uint256" + } + ], + "name": "MaxNodeOperatorsPerExtraDataItemCountSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxPositiveTokenRebase", + "type": "uint256" + } + ], + "name": "MaxPositiveTokenRebaseSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxValidatorExitRequestsPerReport", + "type": "uint256" + } + ], + "name": "MaxValidatorExitRequestsPerReportSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oneOffCLBalanceDecreaseBPLimit", + "type": "uint256" + } + ], + "name": "OneOffCLBalanceDecreaseBPLimitSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "requestTimestampMargin", + "type": "uint256" + } + ], + "name": "RequestTimestampMarginSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "simulatedShareRateDeviationBPLimit", + "type": "uint256" + } + ], + "name": "SimulatedShareRateDeviationBPLimitSet", + "type": "event" + }, + { + "inputs": [], + "name": "ALL_LIMITS_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "APPEARED_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXITED_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_POSITIVE_TOKEN_REBASE_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_timeElapsed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_preCLBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_postCLBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_withdrawalVaultBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_elRewardsVaultBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_sharesRequestedToBurn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_preCLValidators", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_postCLValidators", + "type": "uint256" + } + ], + "name": "checkAccountingOracleReport", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_exitRequestsCount", + "type": "uint256" + } + ], + "name": "checkExitBusOracleReport", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_exitedValidatorsCount", + "type": "uint256" + } + ], + "name": "checkExitedValidatorsRatePerDay", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_extraDataListItemsCount", + "type": "uint256" + } + ], + "name": "checkExtraDataItemsCountPerTransaction", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_itemIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nodeOperatorsCount", + "type": "uint256" + } + ], + "name": "checkNodeOperatorsPerExtraDataItemCount", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_postTotalPooledEther", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_postTotalShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_etherLockedOnWithdrawalQueue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_sharesBurntDueToWithdrawals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_simulatedShareRate", + "type": "uint256" + } + ], + "name": "checkSimulatedShareRate", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_lastFinalizableRequestId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reportTimestamp", + "type": "uint256" + } + ], + "name": "checkWithdrawalQueueOracleReport", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLidoLocator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaxPositiveTokenRebase", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOracleReportLimits", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "exitedValidatorsPerDayLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "oneOffCLBalanceDecreaseBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "annualBalanceIncreaseBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "simulatedShareRateDeviationBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxValidatorExitRequestsPerReport", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxAccountingExtraDataListItemsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxNodeOperatorsPerExtraDataItemCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestTimestampMargin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPositiveTokenRebase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "appearedValidatorsPerDayLimit", + "type": "uint256" + } + ], + "internalType": "struct LimitsList", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_annualBalanceIncreaseBPLimit", + "type": "uint256" + } + ], + "name": "setAnnualBalanceIncreaseBPLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_appearedValidatorsPerDayLimit", + "type": "uint256" + } + ], + "name": "setAppearedValidatorsPerDayLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_exitedValidatorsPerDayLimit", + "type": "uint256" + } + ], + "name": "setExitedValidatorsPerDayLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxAccountingExtraDataListItemsCount", + "type": "uint256" + } + ], + "name": "setMaxAccountingExtraDataListItemsCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxValidatorExitRequestsPerReport", + "type": "uint256" + } + ], + "name": "setMaxExitRequestsPerOracleReport", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxNodeOperatorsPerExtraDataItemCount", + "type": "uint256" + } + ], + "name": "setMaxNodeOperatorsPerExtraDataItemCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxPositiveTokenRebase", + "type": "uint256" + } + ], + "name": "setMaxPositiveTokenRebase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_oneOffCLBalanceDecreaseBPLimit", + "type": "uint256" + } + ], + "name": "setOneOffCLBalanceDecreaseBPLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "exitedValidatorsPerDayLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "oneOffCLBalanceDecreaseBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "annualBalanceIncreaseBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "simulatedShareRateDeviationBPLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxValidatorExitRequestsPerReport", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxAccountingExtraDataListItemsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxNodeOperatorsPerExtraDataItemCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestTimestampMargin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPositiveTokenRebase", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "appearedValidatorsPerDayLimit", + "type": "uint256" + } + ], + "internalType": "struct LimitsList", + "name": "_limitsList", + "type": "tuple" + } + ], + "name": "setOracleReportLimits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_requestTimestampMargin", + "type": "uint256" + } + ], + "name": "setRequestTimestampMargin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_simulatedShareRateDeviationBPLimit", + "type": "uint256" + } + ], + "name": "setSimulatedShareRateDeviationBPLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_preTotalPooledEther", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_preTotalShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_preCLBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_postCLBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_withdrawalVaultBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_elRewardsVaultBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_sharesRequestedToBurn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_etherToLockForWithdrawals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newSharesToBurnForWithdrawals", + "type": "uint256" + } + ], + "name": "smoothenTokenRebase", + "outputs": [ + { + "internalType": "uint256", + "name": "withdrawals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "elRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "simulatedSharesToBurn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sharesToBurn", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] From e968086f25dafac47332162c066417168a661fcb Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 26 Jun 2024 17:28:48 +0200 Subject: [PATCH 033/220] fest: set accint balance with Anvil --- tests/conftest.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 6aea0c93d..c84407360 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -48,7 +48,18 @@ def ldo_holder(accounts): @pytest.fixture(scope="function") def stranger(accounts): stranger = accounts.at("0x98eC059dC3aDFbdd63429454aeB0C990fbA4a124", force=True) - web3.provider.make_request("evm_setAccountBalance", [stranger.address, "0x152D02C7E14AF6800000"]) + if(stranger.balance() != ETH(100000)): + # try Ganache + try: + web3.provider.make_request("evm_setAccountBalance", [stranger.address, "0x152D02C7E14AF6800000"]) + except: + pass + if(stranger.balance() != ETH(100000)): + # try Anvil + try: + web3.provider.make_request("anvil_setBalance", [stranger.address, "0x152D02C7E14AF6800000"]) + except: + pass assert stranger.balance() == ETH(100000) return stranger From 0404406e5fe93f12af53bc4ad684d8b0f9d44ca0 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 26 Jun 2024 18:16:44 +0200 Subject: [PATCH 034/220] feat: make sure that LDO_HOLDER_ADDRESS_FOR_TESTS has some eth before start vote --- utils/import_current_votes.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/utils/import_current_votes.py b/utils/import_current_votes.py index 2a1657b4a..c24db69bb 100644 --- a/utils/import_current_votes.py +++ b/utils/import_current_votes.py @@ -4,7 +4,7 @@ from brownie import accounts from brownie.network.transaction import TransactionReceipt - +from utils.test.helpers import ETH from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS, LIDO_V2_UPGRADE_TEMPLATE, get_is_live, contracts @@ -57,6 +57,13 @@ def start_and_execute_votes(dao_voting, helpers) -> tuple[List[str], List[Transa exec(f"from {name_for_import} import start_vote as {start_vote_name}") start_vote = locals()[start_vote_name] + # before start vote make sure that test account have some ETH + # otherwise start_vote will fail with ValueError: Insufficient funds for gas * price + value + # check voting.py: tx = token_manager.forward(new_vote_script, tx_params) + ldo_holder_for_test = accounts.at(LDO_HOLDER_ADDRESS_FOR_TESTS, True) + if(ldo_holder_for_test.balance() < ETH(1)): + accounts[0].transfer(LDO_HOLDER_ADDRESS_FOR_TESTS, "1 ether") + vote_id, _ = start_vote({"from": LDO_HOLDER_ADDRESS_FOR_TESTS}, silent=True) (tx,) = helpers.execute_votes(accounts, [vote_id], dao_voting, topup="0.5 ether") vote_ids.append(vote_id) From be02029266f6201d6bdc7c3aac3249068dc790de Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Wed, 26 Jun 2024 22:26:56 +0300 Subject: [PATCH 035/220] fix: parse events from receipts --- tests/test_vote_sr_v2_holesky.py | 21 ++++++++++----------- utils/test/tx_tracing_helpers.py | 11 ++++++----- utils/tx_tracing.py | 25 ++++++++++++++++++++----- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index d206ccc25..4a329b303 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -137,11 +137,7 @@ class StakingModuleItem(NamedTuple): ] -def test_vote( - helpers, - accounts, - vote_ids_from_env, -): +def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): staking_router = contracts.staking_router sr_proxy = interface.OssifiableProxy(contracts.staking_router) @@ -200,15 +196,18 @@ def test_vote( # AO check_ossifiable_proxy_impl(ao_proxy, ACCOUNTING_ORACLE_IMPL) - # no prermission to manage consensus version on agent + # no permission to manage consensus version on agent check_manage_consensus_role() # VEBO consensus version assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION # Events check + if bypass_events_decoding: + return + events = group_voting_events(vote_tx) - assert len(events) == 17 + assert len(events) == 45 validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) @@ -389,10 +388,10 @@ def validate_staking_module_update(event: EventDict, module_items: List[StakingM validate_events_chain([e.name for e in event], _events_chain) - assert event.count("StakingModuleFeesSet") == 2 - assert event.count("StakingModuleShareLimitSet") == 2 - assert event.count("StakingModuleMinDepositBlockDistanceSet") == 2 - assert event.count("StakingModuleMaxDepositsPerBlockSet") == 2 + assert event.count("StakingModuleFeesSet") == 3 + assert event.count("StakingModuleShareLimitSet") == 3 + assert event.count("StakingModuleMinDepositBlockDistanceSet") == 3 + assert event.count("StakingModuleMaxDepositsPerBlockSet") == 3 assert event.count("ContractVersionSet") == 1 # curated diff --git a/utils/test/tx_tracing_helpers.py b/utils/test/tx_tracing_helpers.py index b0535f0de..2c49e0c23 100644 --- a/utils/test/tx_tracing_helpers.py +++ b/utils/test/tx_tracing_helpers.py @@ -1,7 +1,8 @@ from utils.tx_tracing import * +from utils.config import VOTING, AGENT, ARAGON_CALLS_SCRIPT _vote_item_group = GroupBy( - contract_name="CallsScript", + contract_addresses=[VOTING, AGENT, ARAGON_CALLS_SCRIPT], event_name="LogScriptCall", group_title="Vote item #", show_counter=True, @@ -9,7 +10,7 @@ ) _service_item_group = GroupBy( - contract_name="Voting", + contract_addresses=[VOTING, AGENT], event_name="ScriptResult", group_title="Service events", show_counter=False, @@ -36,7 +37,7 @@ def display_voting_call_trace(tx: TransactionReceipt) -> None: def count_vote_items_by_events(tx: TransactionReceipt, voting_addr: str) -> int: - events = tx_events_from_trace(tx) + events = tx_events(tx) ev_dict = EventDict(events) calls_slice = ev_dict["LogScriptCall"] @@ -44,14 +45,14 @@ def count_vote_items_by_events(tx: TransactionReceipt, voting_addr: str) -> int: def display_voting_events(tx: TransactionReceipt) -> None: - dict_events = EventDict(tx_events_from_trace(tx)) + dict_events = EventDict(tx_events(tx)) groups = [_vote_item_group, _service_item_group] display_tx_events(dict_events, "Events registered during the vote execution", groups) def group_voting_events(tx: TransactionReceipt) -> List[EventDict]: - events = tx_events_from_trace(tx) + events = tx_events(tx) groups = [_vote_item_group, _service_item_group] grouped_events = group_tx_events(events, EventDict(events), groups) diff --git a/utils/tx_tracing.py b/utils/tx_tracing.py index 4db8fd5ce..63f35c16f 100644 --- a/utils/tx_tracing.py +++ b/utils/tx_tracing.py @@ -3,7 +3,7 @@ from typing import Callable, Dict, Optional, List, Annotated, Tuple from dataclasses import dataclass -from eth_event import StructLogError, decode_traceTransaction +from eth_event import StructLogError, decode_traceTransaction, decode_logs from brownie.network.transaction import TransactionReceipt from brownie.network.transaction import _step_internal, _step_external, _step_compare @@ -17,7 +17,7 @@ @dataclass(eq=True, frozen=True) class GroupBy: - contract_name: str + contract_addresses: List[str] event_name: str group_title: str show_counter: bool @@ -69,6 +69,21 @@ def _find_fist_index_of_event_with_different_from_first_event_address(events): return len(events) +def tx_events(tx: TransactionReceipt) -> Optional[List]: + try: + return tx_events_from_receipt(tx) + except: + return tx_events_from_trace(tx) + + +def tx_events_from_receipt(tx: TransactionReceipt) -> Optional[List]: + if not tx.status: + raise "Tx has reverted status (set to 0)" + + events = decode_logs(tx.logs, _topics, allow_undecoded=True) + return [format_event(i) for i in events] + + def tx_events_from_trace(tx: TransactionReceipt) -> Optional[List]: """ Parse and build events list from transaction receipt @@ -122,9 +137,9 @@ def resolve_contract(addr: str) -> str: return contract._name -def get_event_group(event, contract_name, groups: List[GroupBy]) -> Optional[GroupBy]: +def get_event_group(event, address, groups: List[GroupBy]) -> Optional[GroupBy]: for g in groups: - if g.contract_name == contract_name and g.event_name == event.name: + if address in g.contract_addresses and g.event_name == event.name: return g return None @@ -162,7 +177,7 @@ def group_tx_events( for event in evs[:idx]: event_names.append(event.name) - current_grp = get_event_group(first_event, contract_name, groups) + current_grp = get_event_group(first_event, event.address, groups) if current_grp is not None: if group_stop_index >= group_start_index: ret.append((prev_grp, EventDict(all_evs[group_start_index : group_stop_index + 1]))) From d3804f590de37d140b7fc94cf4b8cb358e3db5d7 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Thu, 27 Jun 2024 10:36:59 +0300 Subject: [PATCH 036/220] fix: group logs from receipt --- tests/test_vote_sr_v2_holesky.py | 4 ++-- utils/test/tx_tracing_helpers.py | 38 +++++++++++++++++++++++++++----- utils/tx_tracing.py | 19 ++++++---------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 4a329b303..23803a62c 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -205,9 +205,9 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): if bypass_events_decoding: return - events = group_voting_events(vote_tx) + events = group_voting_events_from_receipt(vote_tx) - assert len(events) == 45 + assert len(events) == 17 validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) diff --git a/utils/test/tx_tracing_helpers.py b/utils/test/tx_tracing_helpers.py index 2c49e0c23..42d90697a 100644 --- a/utils/test/tx_tracing_helpers.py +++ b/utils/test/tx_tracing_helpers.py @@ -1,8 +1,7 @@ from utils.tx_tracing import * -from utils.config import VOTING, AGENT, ARAGON_CALLS_SCRIPT _vote_item_group = GroupBy( - contract_addresses=[VOTING, AGENT, ARAGON_CALLS_SCRIPT], + contract_name="CallsScript", event_name="LogScriptCall", group_title="Vote item #", show_counter=True, @@ -10,7 +9,7 @@ ) _service_item_group = GroupBy( - contract_addresses=[VOTING, AGENT], + contract_name="Voting", event_name="ScriptResult", group_title="Service events", show_counter=False, @@ -37,7 +36,7 @@ def display_voting_call_trace(tx: TransactionReceipt) -> None: def count_vote_items_by_events(tx: TransactionReceipt, voting_addr: str) -> int: - events = tx_events(tx) + events = tx_events_from_trace(tx) ev_dict = EventDict(events) calls_slice = ev_dict["LogScriptCall"] @@ -45,14 +44,14 @@ def count_vote_items_by_events(tx: TransactionReceipt, voting_addr: str) -> int: def display_voting_events(tx: TransactionReceipt) -> None: - dict_events = EventDict(tx_events(tx)) + dict_events = EventDict(tx_events_from_trace(tx)) groups = [_vote_item_group, _service_item_group] display_tx_events(dict_events, "Events registered during the vote execution", groups) def group_voting_events(tx: TransactionReceipt) -> List[EventDict]: - events = tx_events(tx) + events = tx_events_from_trace(tx) groups = [_vote_item_group, _service_item_group] grouped_events = group_tx_events(events, EventDict(events), groups) @@ -64,3 +63,30 @@ def group_voting_events(tx: TransactionReceipt) -> List[EventDict]: ) return ret + + +def group_voting_events_from_receipt(tx: TransactionReceipt) -> List[EventDict]: + events = tx_events_from_receipt(tx) + + previous_event = None + groups = [] + current_group = None + + for event in events: + is_start_of_new_group = ( + previous_event is None or previous_event["name"] == "ScriptResult" and event["name"] == "LogScriptCall" + ) + + if is_start_of_new_group: + current_group = [] + groups.append(current_group) + + current_group.append(event) + previous_event = event + + event_dict_groups = [] + for group in groups: + events = EventDict(group) + event_dict_groups.append(events) + + return event_dict_groups diff --git a/utils/tx_tracing.py b/utils/tx_tracing.py index 63f35c16f..69da2559b 100644 --- a/utils/tx_tracing.py +++ b/utils/tx_tracing.py @@ -10,6 +10,7 @@ from brownie.network.event import EventDict, _topics from brownie.network import state from brownie.convert.normalize import format_event +from brownie import web3 from brownie.utils import color from brownie.utils.output import build_tree @@ -17,7 +18,7 @@ @dataclass(eq=True, frozen=True) class GroupBy: - contract_addresses: List[str] + contract_name: str event_name: str group_title: str show_counter: bool @@ -69,18 +70,12 @@ def _find_fist_index_of_event_with_different_from_first_event_address(events): return len(events) -def tx_events(tx: TransactionReceipt) -> Optional[List]: - try: - return tx_events_from_receipt(tx) - except: - return tx_events_from_trace(tx) - - def tx_events_from_receipt(tx: TransactionReceipt) -> Optional[List]: if not tx.status: raise "Tx has reverted status (set to 0)" - events = decode_logs(tx.logs, _topics, allow_undecoded=True) + result = web3.provider.make_request("eth_getTransactionReceipt", [tx.txid]) + events = decode_logs(result["result"]["logs"], _topics, allow_undecoded=True) return [format_event(i) for i in events] @@ -137,9 +132,9 @@ def resolve_contract(addr: str) -> str: return contract._name -def get_event_group(event, address, groups: List[GroupBy]) -> Optional[GroupBy]: +def get_event_group(event, contract_name, groups: List[GroupBy]) -> Optional[GroupBy]: for g in groups: - if address in g.contract_addresses and g.event_name == event.name: + if g.contract_name == contract_name and g.event_name == event.name: return g return None @@ -177,7 +172,7 @@ def group_tx_events( for event in evs[:idx]: event_names.append(event.name) - current_grp = get_event_group(first_event, event.address, groups) + current_grp = get_event_group(first_event, contract_name, groups) if current_grp is not None: if group_stop_index >= group_start_index: ret.append((prev_grp, EventDict(all_evs[group_start_index : group_stop_index + 1]))) From 62178cbc90758ebe41d16140b76be1dc1ff5c4e5 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 27 Jun 2024 00:05:12 +0400 Subject: [PATCH 037/220] fix: add easy track for csm --- scripts/holesky/vote_sr_v2_holesky.py | 22 ++++++++++++---------- tests/test_vote_sr_v2_holesky.py | 24 ++++++++++++++---------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/scripts/holesky/vote_sr_v2_holesky.py b/scripts/holesky/vote_sr_v2_holesky.py index fe7f6e695..0c9cceac3 100644 --- a/scripts/holesky/vote_sr_v2_holesky.py +++ b/scripts/holesky/vote_sr_v2_holesky.py @@ -93,8 +93,11 @@ CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 CS_ORACLE_INITIAL_EPOCH = 58050 +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0x07696EA8A5b53C3E35d9cce10cc62c6c79C4691D" + + description = """ -_REPLACE_ME_ +Proposal to support DSM 2.0 and CSM Module """ @@ -157,7 +160,6 @@ def get_repo_version(repo_address: str) -> tuple[int, int, int]: def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: """Prepare and run voting.""" - nor_repo = contracts.nor_app_repo.address simple_dvt_repo = contracts.simple_dvt_app_repo.address sandbox_repo = contracts.sandbox_repo.address @@ -376,13 +378,13 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ] ), ), - # ( - # "28. Add CS settle EL stealing factory to ET", - # add_evmscript_factory( - # factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, - # permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), - # ), - # ), + ( + "28. Add CS settle EL stealing factory to ET", + add_evmscript_factory( + factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, + permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), + ), + ), ( "29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT}", agent_forward( @@ -415,7 +417,7 @@ def main(): if get_is_live(): tx_params["priority_fee"] = get_priority_fee() - vote_id, _ = start_vote(tx_params=tx_params, silent=True) # disable IPFS description for Holesky + vote_id, _ = start_vote(tx_params=tx_params, silent=True) # disable IPFS description for Holesky vote_id >= 0 and print(f"Vote created: {vote_id}.") diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 23803a62c..0cf3ad579 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -24,6 +24,7 @@ from utils.test.event_validators.aragon import validate_app_update_event from typing import NamedTuple + class StakingModuleItem(NamedTuple): id: int staking_module_fee: int @@ -64,7 +65,9 @@ class StakingModuleItem(NamedTuple): old_nor_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" -old_sdvt_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +old_sdvt_uri = ( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +) sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" CURATED_MODULE_BEFORE_VOTE = { @@ -139,7 +142,6 @@ class StakingModuleItem(NamedTuple): def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): staking_router = contracts.staking_router - sr_proxy = interface.OssifiableProxy(contracts.staking_router) locator_proxy = interface.OssifiableProxy(contracts.lido_locator) nor_proxy = interface.AppProxyUpgradeable(contracts.node_operators_registry) @@ -147,7 +149,7 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): ao_proxy = interface.OssifiableProxy(contracts.accounting_oracle) vebo_proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) - assert staking_router.getStakingModulesCount() == 3 # curated + simpledvt + sandbox + assert staking_router.getStakingModulesCount() == 3 # curated + simpledvt + sandbox # Before voting tests # locator @@ -178,13 +180,15 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): if len(vote_ids_from_env) > 0: (vote_id,) = vote_ids_from_env else: - tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS, "priority_fee": get_priority_fee()} + tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS, "priority_fee": get_priority_fee()} vote_id, _ = start_vote(tx_params, silent=True) vote_tx = helpers.execute_vote(accounts, vote_id, contracts.voting) print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") + assert staking_router.getStakingModulesCount() == 4 + # locator check_ossifiable_proxy_impl(locator_proxy, LIDO_LOCATOR_IMPL) # DSM @@ -279,13 +283,13 @@ def check_dsm_roles_before_vote(): assert old_dsm_has_pause_role - # print(contracts.staking_router) - # print(contracts.deposit_security_module_v2) - # old_dsm_has_resume_role = contracts.staking_router.hasRole( - # STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 - # ) + print(contracts.staking_router) + print(contracts.deposit_security_module_v2) + old_dsm_has_resume_role = contracts.staking_router.hasRole( + STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 + ) - # assert old_dsm_has_resume_role + assert old_dsm_has_resume_role def check_dsm_roles_after_vote(): From 3e3c1f62e8cb7b0a6fae475c3ed7064f50d10443 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 27 Jun 2024 12:44:27 +0400 Subject: [PATCH 038/220] fix: group of events --- utils/test/tx_tracing_helpers.py | 40 ++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/utils/test/tx_tracing_helpers.py b/utils/test/tx_tracing_helpers.py index 42d90697a..503549a72 100644 --- a/utils/test/tx_tracing_helpers.py +++ b/utils/test/tx_tracing_helpers.py @@ -65,25 +65,57 @@ def group_voting_events(tx: TransactionReceipt) -> List[EventDict]: return ret +# def group_voting_events_from_receipt(tx: TransactionReceipt) -> List[EventDict]: +# events = tx_events_from_receipt(tx) + +# previous_event = None +# groups = [] +# current_group = None + +# for event in events: +# is_start_of_new_group = ( +# previous_event is None or previous_event["name"] == "ScriptResult" and event["name"] == "LogScriptCall" +# ) + +# if is_start_of_new_group: +# current_group = [] +# groups.append(current_group) + +# current_group.append(event) +# previous_event = event + +# event_dict_groups = [] +# for group in groups: +# events = EventDict(group) +# event_dict_groups.append(events) + +# return event_dict_groups + + def group_voting_events_from_receipt(tx: TransactionReceipt) -> List[EventDict]: events = tx_events_from_receipt(tx) previous_event = None groups = [] - current_group = None + current_group = [] for event in events: - is_start_of_new_group = ( - previous_event is None or previous_event["name"] == "ScriptResult" and event["name"] == "LogScriptCall" + is_start_of_new_group = previous_event is not None and ( + previous_event["name"] == "ScriptResult" + or event["name"] == "LogScriptCall" + and previous_event["name"] != "LogScriptCall" ) if is_start_of_new_group: - current_group = [] groups.append(current_group) + current_group = [] current_group.append(event) previous_event = event + if current_group: + groups.append(current_group) + event_dict_groups = [] for group in groups: events = EventDict(group) From 7b3c3395856822c4a5ba4b16326ac7c09fcb6db2 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Thu, 27 Jun 2024 12:11:14 +0300 Subject: [PATCH 039/220] fix: events grouping --- tests/test_vote_sr_v2_holesky.py | 2 +- utils/test/tx_tracing_helpers.py | 43 +++----------------------------- 2 files changed, 5 insertions(+), 40 deletions(-) diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 0cf3ad579..47c61a3cf 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -211,7 +211,7 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): events = group_voting_events_from_receipt(vote_tx) - assert len(events) == 17 + assert len(events) == 29 validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) diff --git a/utils/test/tx_tracing_helpers.py b/utils/test/tx_tracing_helpers.py index 503549a72..5dd71d9f1 100644 --- a/utils/test/tx_tracing_helpers.py +++ b/utils/test/tx_tracing_helpers.py @@ -1,4 +1,5 @@ from utils.tx_tracing import * +from utils.config import VOTING _vote_item_group = GroupBy( contract_name="CallsScript", @@ -65,56 +66,20 @@ def group_voting_events(tx: TransactionReceipt) -> List[EventDict]: return ret -# def group_voting_events_from_receipt(tx: TransactionReceipt) -> List[EventDict]: -# events = tx_events_from_receipt(tx) - -# previous_event = None -# groups = [] -# current_group = None - -# for event in events: -# is_start_of_new_group = ( -# previous_event is None or previous_event["name"] == "ScriptResult" and event["name"] == "LogScriptCall" -# ) - -# if is_start_of_new_group: -# current_group = [] -# groups.append(current_group) - -# current_group.append(event) -# previous_event = event - -# event_dict_groups = [] -# for group in groups: -# events = EventDict(group) -# event_dict_groups.append(events) - -# return event_dict_groups - - def group_voting_events_from_receipt(tx: TransactionReceipt) -> List[EventDict]: events = tx_events_from_receipt(tx) - previous_event = None groups = [] - current_group = [] + current_group = None for event in events: - is_start_of_new_group = previous_event is not None and ( - previous_event["name"] == "ScriptResult" - or event["name"] == "LogScriptCall" - and previous_event["name"] != "LogScriptCall" - ) + is_start_of_new_group = event["name"] == "LogScriptCall" and event["address"] == VOTING if is_start_of_new_group: - groups.append(current_group) current_group = [] + groups.append(current_group) current_group.append(event) - previous_event = event - - if current_group: - groups.append(current_group) event_dict_groups = [] for group in groups: From c11e66a793133154d2b6ca9ee075aa0e91d04e8c Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 27 Jun 2024 14:00:06 +0400 Subject: [PATCH 040/220] fix: part of tests on holesky --- tests/test_vote_sr_v2_holesky.py | 51 +++++++++++++++++++++++++------- utils/import_current_votes.py | 5 ++-- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 47c61a3cf..4e7340e87 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -64,7 +64,8 @@ class StakingModuleItem(NamedTuple): SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 old_nor_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" +nor_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +# "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" old_sdvt_uri = ( "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ) @@ -243,7 +244,8 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): nor_new_app = contracts.nor_app_repo.getLatest() assert_repo_update(nor_new_app, nor_old_app, NODE_OPERATORS_REGISTRY_IMPL, nor_uri) - validate_repo_upgrade_event(events[6], RepoUpgrade(6, nor_new_app[0])) + print(f"event {events[6]}") + validate_repo_upgrade_event(events[6], RepoUpgrade(2, nor_new_app[0])) validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL) validate_nor_update(events[8], NOR_VERSION) @@ -253,19 +255,22 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL) validate_nor_update(events[11], SDVT_VERSION) + # print(f"events {events[12]}") + + # assert False # AO - validate_upgrade_events(events[12], ACCOUNTING_ORACLE_IMPL) - validate_ao_update(events[13], AO_VERSION, AO_CONSENSUS_VERSION) + # validate_upgrade_events(events[12], ACCOUNTING_ORACLE_IMPL) + # validate_ao_update(events[13], AO_VERSION, AO_CONSENSUS_VERSION) - validate_grant_role_event( - events[14], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address - ) + # validate_grant_role_event( + # events[14], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + # ) - validate_vebo_consensus_version_set(events[15]) + # validate_vebo_consensus_version_set(events[15]) - validate_revoke_role_event( - events[16], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address - ) + # validate_revoke_role_event( + # events[16], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + # ) def check_ossifiable_proxy_impl(proxy, expected_impl): @@ -375,6 +380,7 @@ def validate_dsm_roles_events(events: EventDict): def validate_staking_module_update(event: EventDict, module_items: List[StakingModuleItem]): + assert len(module_items) == 2 _events_chain = [ @@ -387,9 +393,32 @@ def validate_staking_module_update(event: EventDict, module_items: List[StakingM "StakingModuleFeesSet", "StakingModuleMaxDepositsPerBlockSet", "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", "ContractVersionSet", ] + evs = [ + "LogScriptCall", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ContractVersionSet", + ] + + # print(f"events {[e.name for e in event]}") + validate_events_chain([e.name for e in event], _events_chain) assert event.count("StakingModuleFeesSet") == 3 diff --git a/utils/import_current_votes.py b/utils/import_current_votes.py index c24db69bb..e77b6d62e 100644 --- a/utils/import_current_votes.py +++ b/utils/import_current_votes.py @@ -5,7 +5,7 @@ from brownie import accounts from brownie.network.transaction import TransactionReceipt from utils.test.helpers import ETH -from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS, LIDO_V2_UPGRADE_TEMPLATE, get_is_live, contracts +from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS, get_is_live, contracts def get_vote_scripts_dir() -> str: @@ -20,6 +20,7 @@ def get_vote_script_files() -> List[str]: vote_files = glob.glob(os.path.join(dir_path, "vote_*.py")) return vote_files + def get_upgrade_script_files() -> List[str]: """Return List of abs paths to vote scripts""" dir_path = get_vote_scripts_dir() @@ -61,7 +62,7 @@ def start_and_execute_votes(dao_voting, helpers) -> tuple[List[str], List[Transa # otherwise start_vote will fail with ValueError: Insufficient funds for gas * price + value # check voting.py: tx = token_manager.forward(new_vote_script, tx_params) ldo_holder_for_test = accounts.at(LDO_HOLDER_ADDRESS_FOR_TESTS, True) - if(ldo_holder_for_test.balance() < ETH(1)): + if ldo_holder_for_test.balance() < ETH(1): accounts[0].transfer(LDO_HOLDER_ADDRESS_FOR_TESTS, "1 ether") vote_id, _ = start_vote({"from": LDO_HOLDER_ADDRESS_FOR_TESTS}, silent=True) From b36b31efe5a5683c265ef4d89276eb0b137439b8 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 27 Jun 2024 14:21:57 +0400 Subject: [PATCH 041/220] fix: remaining part of tests --- tests/test_vote_sr_v2_holesky.py | 34 +++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 4e7340e87..67733e8aa 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -10,6 +10,7 @@ SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL, ACCOUNTING_ORACLE_IMPL, + SANDBOX_IMPL, ) from scripts.holesky.vote_sr_v2_holesky import start_vote from utils.config import ( @@ -43,6 +44,7 @@ class StakingModuleItem(NamedTuple): OLD_SR_IMPL_ADDRESS = "0x32f236423928c2c138f46351d9e5fd26331b1aa4" OLD_NOR_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" OLD_SDVT_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" +OLD_SANDBOX_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" OLD_ACCOUNTING_ORACLE_IMPL = "0x6aca050709469f1f98d8f40f68b1c83b533cd2b2" CURATED_MODULE_ID = 1 SIMPLE_DVT_MODULE_ID = 2 @@ -70,6 +72,7 @@ class StakingModuleItem(NamedTuple): "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ) sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" +sandbox_uri = "0x697066733a516d5839414675394e456d76704b634336747a4a79684543316b7276344a5a72695767473951634d6e6e657a5165" CURATED_MODULE_BEFORE_VOTE = { "id": 1, @@ -147,6 +150,7 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): locator_proxy = interface.OssifiableProxy(contracts.lido_locator) nor_proxy = interface.AppProxyUpgradeable(contracts.node_operators_registry) sdvt_proxy = interface.AppProxyUpgradeable(contracts.simple_dvt) + sandbox_proxy = interface.AppProxyUpgradeable(contracts.sandbox) ao_proxy = interface.OssifiableProxy(contracts.accounting_oracle) vebo_proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) @@ -169,6 +173,11 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): sdvt_old_app = contracts.simple_dvt_app_repo.getLatest() assert sdvt_proxy.implementation() == OLD_SDVT_IMPL assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, sdvt_uri) + # Sanbox + + sandbox_old_app = contracts.sandbox_repo.getLatest() + assert sandbox_proxy.implementation() == OLD_SANDBOX_IMPL + assert_repo_before_vote(sandbox_old_app, 1, OLD_SDVT_IMPL, sandbox_uri) # AO check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) # no prermission to manage consensus version on agent @@ -255,22 +264,25 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL) validate_nor_update(events[11], SDVT_VERSION) - # print(f"events {events[12]}") + sandbox_new_app = contracts.sandbox_repo.getLatest() + assert_repo_update(sandbox_new_app, sandbox_old_app, SANDBOX_IMPL, sandbox_uri) + validate_repo_upgrade_event(events[12], RepoUpgrade(2, sandbox_new_app[0])) + # validate_app_update_event(events[13], SANDBOX_DVT_ARAGON_APP_ID, SANDBOX_DVT_IMPL) + # validate_nor_update(events[14], SANDBOX_VERSION) - # assert False # AO - # validate_upgrade_events(events[12], ACCOUNTING_ORACLE_IMPL) - # validate_ao_update(events[13], AO_VERSION, AO_CONSENSUS_VERSION) + validate_upgrade_events(events[15], ACCOUNTING_ORACLE_IMPL) + validate_ao_update(events[16], AO_VERSION, AO_CONSENSUS_VERSION) - # validate_grant_role_event( - # events[14], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address - # ) + validate_grant_role_event( + events[17], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + ) - # validate_vebo_consensus_version_set(events[15]) + validate_vebo_consensus_version_set(events[18]) - # validate_revoke_role_event( - # events[16], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address - # ) + validate_revoke_role_event( + events[19], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + ) def check_ossifiable_proxy_impl(proxy, expected_impl): From fae472fac98ad8db6d03dd119d8aa77949f76a2a Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 27 Jun 2024 14:59:31 +0400 Subject: [PATCH 042/220] fix: remaining part of tests --- tests/test_vote_sr_v2_holesky.py | 35 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 67733e8aa..7b09f098f 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -115,6 +115,26 @@ class StakingModuleItem(NamedTuple): } ) +CS_MODULE_NAME = "CommunityStaking" +CS_STAKE_SHARE_LIMIT = 2000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 +CS_STAKING_MODULE_FEE = 800 +CS_TREASURY_FEE = 200 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 58050 + +CSM_AFTER_VOTE = { + "id": 4, + "name": CS_MODULE_NAME, + "stakingModuleFee": CS_STAKING_MODULE_FEE, + "treasuryFee": CS_TREASURY_FEE, + "targetShare": CS_STAKE_SHARE_LIMIT, + "priorityExitShareThreshold": CS_PRIORITY_EXIT_SHARE_THRESHOLD, + "maxDepositsPerBlock": CS_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": CS_MIN_DEPOSIT_BLOCK_DISTANCE, +} + OLD_SR_ABI = bi = [ { "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], @@ -409,19 +429,6 @@ def validate_staking_module_update(event: EventDict, module_items: List[StakingM "StakingModuleFeesSet", "StakingModuleMaxDepositsPerBlockSet", "StakingModuleMinDepositBlockDistanceSet", - "ContractVersionSet", - ] - - evs = [ - "LogScriptCall", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", "StakingModuleShareLimitSet", "StakingModuleFeesSet", "StakingModuleMaxDepositsPerBlockSet", @@ -429,8 +436,6 @@ def validate_staking_module_update(event: EventDict, module_items: List[StakingM "ContractVersionSet", ] - # print(f"events {[e.name for e in event]}") - validate_events_chain([e.name for e in event], _events_chain) assert event.count("StakingModuleFeesSet") == 3 From fc9c9016fcda42780839d38e2fa7610d045bb67e Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 27 Jun 2024 18:06:21 +0400 Subject: [PATCH 043/220] fix: more tests --- scripts/holesky/vote_sr_v2_holesky.py | 54 ++++++--------------- tests/test_vote_sr_v2_holesky.py | 70 +++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 45 deletions(-) diff --git a/scripts/holesky/vote_sr_v2_holesky.py b/scripts/holesky/vote_sr_v2_holesky.py index 0c9cceac3..b5825e49d 100644 --- a/scripts/holesky/vote_sr_v2_holesky.py +++ b/scripts/holesky/vote_sr_v2_holesky.py @@ -23,15 +23,13 @@ CSM -21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE -22. Add staking module -23. Grant request burn role to CSAccounting contract -24. Grant resume role to agent -25. Resume staking module -26. Revoke resume role from agent -27. Update initial epoch -28. Add CS settle EL stealing factory to ET -29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} +21. Add staking module +22. Grant request burn role to CSAccounting contract +23. Grant resume role to agent +24. Resume staking module +25. Revoke resume role from agent +26. Update initial epoch +27. Add CS settle EL stealing factory to ET """ import time @@ -296,19 +294,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # CSM # ( - "21. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE", - agent_forward( - [ - encode_oz_grant_role( - contract=contracts.staking_router, - role_name="STAKING_MODULE_MANAGE_ROLE", - grant_to=contracts.agent, - ) - ] - ), - ), - ( - "22. Add staking module", + "21. Add staking module", agent_forward( [ ( @@ -328,7 +314,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "23. Grant request burn role to CSAccounting contract", + "22. Grant request burn role to CSAccounting contract", agent_forward( [ encode_oz_grant_role( @@ -340,7 +326,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "24. Grant resume role to agent", + "23. Grant resume role to agent", agent_forward( [ encode_oz_grant_role( @@ -352,11 +338,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "25. Resume staking module", + "24. Resume staking module", agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), ), ( - "26. Revoke resume role from agent", + "25. Revoke resume role from agent", agent_forward( [ encode_oz_revoke_role( @@ -368,7 +354,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "27. Update initial epoch", + "26. Update initial epoch", agent_forward( [ ( @@ -379,24 +365,12 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "28. Add CS settle EL stealing factory to ET", + "27. Add CS settle EL stealing factory to ET", add_evmscript_factory( factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), ), ), - ( - "29. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT}", - agent_forward( - [ - encode_oz_revoke_role( - contract=contracts.staking_router, - role_name="STAKING_MODULE_MANAGE_ROLE", - revoke_from=contracts.agent, - ) - ] - ), - ), ) vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 7b09f098f..5c4522084 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -11,6 +11,7 @@ SIMPLE_DVT_IMPL, ACCOUNTING_ORACLE_IMPL, SANDBOX_IMPL, + CS_ACCOUNTING_ADDRESS, ) from scripts.holesky.vote_sr_v2_holesky import start_vote from utils.config import ( @@ -40,6 +41,9 @@ class StakingModuleItem(NamedTuple): PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" +STAKING_MODULE_MANAGE_ROLE = "0x3105bcbf19d4417b73ae0e58d508a65ecf75665e46c2622d8521732de6080c48" +REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" +RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" OLD_LOCATOR_IMPL_ADDRESS = "0xDba5Ad530425bb1b14EECD76F1b4a517780de537" OLD_SR_IMPL_ADDRESS = "0x32f236423928c2c138f46351d9e5fd26331b1aa4" OLD_NOR_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" @@ -206,6 +210,12 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): # VEBO consensus version assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 + assert not contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) + + # had a role + # assert contracts.staking_router.hasRole(STAKING_MODULE_MANAGE_ROLE, contracts.agent.address) + # START VOTE if len(vote_ids_from_env) > 0: (vote_id,) = vote_ids_from_env @@ -235,13 +245,18 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): # VEBO consensus version assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION + assert contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) + + assert contracts.csmHashConsensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + # Events check if bypass_events_decoding: return events = group_voting_events_from_receipt(vote_tx) - assert len(events) == 29 + assert len(events) == 27 validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) @@ -273,7 +288,6 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): nor_new_app = contracts.nor_app_repo.getLatest() assert_repo_update(nor_new_app, nor_old_app, NODE_OPERATORS_REGISTRY_IMPL, nor_uri) - print(f"event {events[6]}") validate_repo_upgrade_event(events[6], RepoUpgrade(2, nor_new_app[0])) validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL) validate_nor_update(events[8], NOR_VERSION) @@ -304,6 +318,18 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): events[19], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address ) + # 20 - add of staking module + + # validate_module_add(events[20], CSM_AFTER_VOTE) + validate_grant_role_event(events[21], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, contracts.agent.address) + validate_grant_role_event(events[22], RESUME_ROLE, contracts.agent.address, contracts.agent.address) + + validate_resume_event(events[23]) + validate_revoke_role_event(events[24], RESUME_ROLE, contracts.agent.address, contracts.agent.address) + validate_updateInitial_epoch(events[25]) + + check_csm() + def check_ossifiable_proxy_impl(proxy, expected_impl): current_impl_address = proxy.proxy__getImplementation() @@ -319,9 +345,6 @@ def check_dsm_roles_before_vote(): old_dsm_has_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) assert old_dsm_has_pause_role - - print(contracts.staking_router) - print(contracts.deposit_security_module_v2) old_dsm_has_resume_role = contracts.staking_router.hasRole( STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 ) @@ -388,6 +411,18 @@ def assert_repo_update(new_app, old_app, contract_address, old_content_uri): assert new_app[2] == old_content_uri, "Content uri should match" +def check_csm(): + cs = contracts.staking_router.getStakingModule(4) + + assert cs["name"] == CSM_AFTER_VOTE["name"] + assert cs["stakingModuleFee"] == CSM_AFTER_VOTE["stakingModuleFee"] + assert cs["treasuryFee"] == CSM_AFTER_VOTE["treasuryFee"] + assert cs["stakeShareLimit"] == CSM_AFTER_VOTE["targetShare"] + assert cs["priorityExitShareThreshold"] == CSM_AFTER_VOTE["priorityExitShareThreshold"] + assert cs["maxDepositsPerBlock"] == CSM_AFTER_VOTE["maxDepositsPerBlock"] + assert cs["minDepositBlockDistance"] == CSM_AFTER_VOTE["minDepositBlockDistance"] + + # Events check @@ -515,3 +550,28 @@ def validate_vebo_consensus_version_set(event: EventDict): _events_chain = ["LogScriptCall", "LogScriptCall", "ConsensusVersionSet", "ScriptResult"] validate_events_chain([e.name for e in event], _events_chain) assert event["ConsensusVersionSet"]["version"] == VEBO_CONSENSUS_VERSION + + +def validate_resume_event(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "Resumed", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event.count("Resumed") == 1 + + +def validate_updateInitial_epoch(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "FrameConfigSet", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event["FrameConfigSet"]["newInitialEpoch"] == CS_ORACLE_INITIAL_EPOCH + + +def validate_module_add(event, csm): + _events_chain = [ + "LogScriptCall", + "StakingRouterETHDeposited", + "StakingModuleAdded", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ScriptResult", + ] + validate_events_chain([e.name for e in event], _events_chain) From 6f8963750097fef46c3a1f09e53cd66cc55d3693 Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 27 Jun 2024 17:03:25 +0200 Subject: [PATCH 044/220] test: update NOR version --- configs/config_mainnet.py | 2 ++ tests/acceptance/test_node_operators_registry.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 12c28f062..4c27d9f1a 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -126,6 +126,8 @@ NODE_OPERATORS_REGISTRY_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" # set address here after SR V2 deploy ## see NodeOperatorsRegistry's proxy appId() NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" +NODE_OPERATORS_REGISTRY_VERSION = 3 + CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY = 432000 CURATED_STAKING_MODULE_TARGET_SHARE_BP = 10000 CURATED_STAKING_MODULE_MODULE_FEE_BP = 500 diff --git a/tests/acceptance/test_node_operators_registry.py b/tests/acceptance/test_node_operators_registry.py index a019a82e0..0c8b14a12 100644 --- a/tests/acceptance/test_node_operators_registry.py +++ b/tests/acceptance/test_node_operators_registry.py @@ -6,6 +6,7 @@ NODE_OPERATORS_REGISTRY, NODE_OPERATORS_REGISTRY_IMPL, NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + NODE_OPERATORS_REGISTRY_VERSION, CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY, CURATED_STAKING_MODULE_OPERATORS_COUNT, CURATED_STAKING_MODULE_OPERATORS_ACTIVE_COUNT, @@ -39,7 +40,7 @@ def test_role_keccaks(contract): def test_versioned(contract): - assert contract.getContractVersion() == 2 + assert contract.getContractVersion() == NODE_OPERATORS_REGISTRY_VERSION def test_initialize(contract): From 02a2a9b0814362553949e305c80bd3723c77d031 Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 27 Jun 2024 17:13:30 +0200 Subject: [PATCH 045/220] test: fix dsm --- configs/config_mainnet.py | 3 +-- tests/acceptance/test_dsm.py | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 4c27d9f1a..7a0340c50 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -190,8 +190,7 @@ # DepositSecurityModule DEPOSIT_SECURITY_MODULE = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact -DSM_MAX_DEPOSITS_PER_BLOCK = 150 -DSM_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +DSM_MAX_OPERATORS_PER_UNVETTING = 200 DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS = 6646 ## Migrated from LIDO_DEPOSIT_SECURITY_MODULE_V1 DSM_GUARDIANS = [ diff --git a/tests/acceptance/test_dsm.py b/tests/acceptance/test_dsm.py index ebf5e21d3..e1e8694db 100644 --- a/tests/acceptance/test_dsm.py +++ b/tests/acceptance/test_dsm.py @@ -6,8 +6,7 @@ DEPOSIT_SECURITY_MODULE, DSM_GUARDIANS, CHAIN_DEPOSIT_CONTRACT, - DSM_MAX_DEPOSITS_PER_BLOCK, - DSM_MIN_DEPOSIT_BLOCK_DISTANCE, + DSM_MAX_OPERATORS_PER_UNVETTING, DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS, DSM_GUARDIAN_QUORUM, ) @@ -29,8 +28,7 @@ def test_links(dsm): def test_deposit_security_module(dsm): - assert dsm.getMaxDeposits() == DSM_MAX_DEPOSITS_PER_BLOCK - assert dsm.getMinDepositBlockDistance() == DSM_MIN_DEPOSIT_BLOCK_DISTANCE + assert dsm.getMaxOperatorsPerUnvetting() == DSM_MAX_OPERATORS_PER_UNVETTING assert dsm.getPauseIntentValidityPeriodBlocks() == DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS assert dsm.getGuardians() == DSM_GUARDIANS From fbbd7720579c27ea9f485a5d4eea132465ab7a0d Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 27 Jun 2024 17:26:17 +0200 Subject: [PATCH 046/220] test: update constants --- configs/config_mainnet.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 7a0340c50..bb75d4f25 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -172,7 +172,8 @@ # OracleReportSanityChecker ORACLE_REPORT_SANITY_CHECKER = "0x9305c1Dbfe22c12c66339184C0025d7006f0f1cC" -CHURN_VALIDATORS_PER_DAY_LIMIT = 20000 +APPEARED_VALIDATORS_PER_DAY_LIMIT = 9000 +EXITED_VALIDATORS_PER_DAY_LIMIT = 43200 ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT = 500 # 5% ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT = 50 # 0.5% @@ -210,7 +211,7 @@ HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 -AO_CONSENSUS_VERSION = 1 +AO_CONSENSUS_VERSION = 2 # ValidatorsExitBusOracle VALIDATORS_EXIT_BUS_ORACLE = "0x0De4Ea0184c2ad0BacA7183356Aea5B8d5Bf5c6e" From 1cc02b3825640eabe99b1b389d20249573eca04c Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 27 Jun 2024 17:50:05 +0200 Subject: [PATCH 047/220] test: replace isTargetLimitActive to targetLimitMode --- tests/acceptance/test_node_operators_registry.py | 7 +------ tests/acceptance/test_simple_dvt_module.py | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/acceptance/test_node_operators_registry.py b/tests/acceptance/test_node_operators_registry.py index 0c8b14a12..27f9f6d2d 100644 --- a/tests/acceptance/test_node_operators_registry.py +++ b/tests/acceptance/test_node_operators_registry.py @@ -114,12 +114,7 @@ def test_nor_state(contract): node_operator_summary = contract.getNodeOperatorSummary(id) exited_node_operators = [12, 1] # NO id 12 was added on vote 23-05-23, NO id 1 was added on vote 03-10-23 - if id in exited_node_operators: - assert ( - node_operator_summary["isTargetLimitActive"] is True - ), f"isTargetLimitActive is inactive for node {id}" - else: - assert node_operator_summary["isTargetLimitActive"] is False, f"isTargetLimitActive is active for node {id}" + assert node_operator_summary["targetLimitMode"] == (1 if id in exited_node_operators else 0) assert node_operator_summary["targetValidatorsCount"] == 0 # Can be more than 0 in regular protocol operations # assert node_operator_summary["stuckValidatorsCount"] == 0 diff --git a/tests/acceptance/test_simple_dvt_module.py b/tests/acceptance/test_simple_dvt_module.py index 47e930c71..000676273 100644 --- a/tests/acceptance/test_simple_dvt_module.py +++ b/tests/acceptance/test_simple_dvt_module.py @@ -127,12 +127,7 @@ def test_simple_dvt_state(contract): assert node_operator["totalVettedValidators"] <= node_operator["totalAddedValidators"] node_operator_summary = contract.getNodeOperatorSummary(id) - if id in exited_node_operators: - assert ( - node_operator_summary["isTargetLimitActive"] is True - ), f"isTargetLimitActive is inactive for node {id}" - else: - assert node_operator_summary["isTargetLimitActive"] is False, f"isTargetLimitActive is active for node {id}" + assert node_operator_summary["targetLimitMode"] == (1 if id in exited_node_operators else 0) assert node_operator_summary["targetValidatorsCount"] == 0 # Can be more than 0 in regular protocol operations # assert node_operator_summary["stuckValidatorsCount"] == 0 From 819c2ce7a98ce3f64a87cf2f868e8398f89a4d1c Mon Sep 17 00:00:00 2001 From: Eddort Date: Thu, 27 Jun 2024 18:23:21 +0200 Subject: [PATCH 048/220] fix: deploy params --- configs/config_holesky.py | 16 ++++++++-------- scripts/holesky/vote_sr_v2_holesky.py | 14 +++++++------- tests/test_vote_sr_v2_holesky.py | 14 +++++++------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/configs/config_holesky.py b/configs/config_holesky.py index 9b9229d49..e63d7e673 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -24,7 +24,7 @@ LEGACY_ORACLE = "0x072f72BE3AcFE2c52715829F2CD9061A6C8fF019" NODE_OPERATORS_REGISTRY = "0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" # set address here after deploy -NODE_OPERATORS_REGISTRY_IMPL = "0x4d75529C753eef6e18F2D37D13508FC5035Ec95e" # set address here after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x605A3AFadF35A8a8fa4f4Cd4fe34a09Bbcea7718" # set address here after SR V2 deploy # Aragon APM Repos VOTING_REPO = "0x2997EA0D07D79038D83Cb04b3BB9A2Bc512E3fDA" @@ -78,20 +78,20 @@ LIDO_LOCATOR = "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8" -LIDO_LOCATOR_IMPL = "0xdcc2dD90186602f29Dfb0C8A65c9BD4d237090Ed" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0xab89ED3D8f31bcF8BB7De53F02084d1e6F043D34" # set address here after SR V2 deploy WITHDRAWAL_QUEUE = "0xc7cc160b58F8Bb0baC94b80847E2CF2800565C50" ORACLE_DAEMON_CONFIG = "0xC01fC1F2787687Bc656EAc0356ba9Db6e6b7afb7" -ORACLE_REPORT_SANITY_CHECKER = "0x7A4D8dF25f2A43505940232aC1397235899Fa8C" # set address here after SR V2 deploy +ORACLE_REPORT_SANITY_CHECKER = "0xd7C870777e08325Ad0A3A85F41E66E7D84B63E4f" # set address here after SR V2 deploy BURNER = "0x4E46BD7147ccf666E1d73A3A456fC7a68de82eCA" -DEPOSIT_SECURITY_MODULE = "0x389D2352b39962cE98D990a979639C1E07ed500f" # set address here after SR V2 deploy +DEPOSIT_SECURITY_MODULE = "0x808DE3b26Be9438F12E9B45528955EA94C17f217" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0x045dd46212A178428c088573A7d102B9d89a022A" # dsm address before SR V2 enact ACCOUNTING_ORACLE = "0x4E97A3972ce8511D87F334dA17a2C332542a5246" -ACCOUNTING_ORACLE_IMPL = "0xFA6DD77332A32858f472c423d7fA79b99EEF386c" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0x748CE008ac6b15634ceD5a6083796f75695052a2" # set address here after SR V2 deploy VALIDATORS_EXIT_BUS_ORACLE = "0xffDDF7025410412deaa05E3E1cE68FE53208afcb" EIP712_STETH = "0xE154732c5Eab277fd88a9fF6Bdff7805eD97BCB1" STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" -STAKING_ROUTER_IMPL = "0x38CE89269bF7145769a867F355B492a867e26Ab5" # set address here after SR V2 deploy +STAKING_ROUTER_IMPL = "0x9b5890E950E3Df487Bb64E0A6743cdE791139152" # set address here after SR V2 deploy WITHDRAWAL_VAULT_IMPL = "0xd517d9d04DA9B47dA23df91261bd3bF435BE964A" @@ -108,13 +108,13 @@ SANDBOX_APP_ID = "0x85d2fceef13a6c14c43527594f79fb91a8ef8f15024a43486efac8df2b11e632" SIMPLE_DVT = "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6" -SIMPLE_DVT_IMPL = "0x4d75529C753eef6e18F2D37D13508FC5035Ec95e" # same as for NOR +SIMPLE_DVT_IMPL = "0x605A3AFadF35A8a8fa4f4Cd4fe34a09Bbcea7718" # same as for NOR SIMPLE_DVT_REPO = "0x889dB59baf032E1dfD4fCA720e0833c24f1404C6" SANDBOX = "0xD6C2ce3BB8bea2832496Ac8b5144819719f343AC" +SANDBOX_IMPL = "0x605A3AFadF35A8a8fa4f4Cd4fe34a09Bbcea7718" SANDBOX_REPO = "0x00E75B5527a876B3F10C23436a0b896C626812d0" - CSM = "0x4562c3e63c2e586cD1651B958C22F88135aCAd4f" CS_ACCOUNTING_ADDRESS = "0xc093e53e8F4b55A223c18A2Da6fA00e60DD5EFE1" CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xbF38618Ea09B503c1dED867156A0ea276Ca1AE37" diff --git a/scripts/holesky/vote_sr_v2_holesky.py b/scripts/holesky/vote_sr_v2_holesky.py index b5825e49d..ee64c8aeb 100644 --- a/scripts/holesky/vote_sr_v2_holesky.py +++ b/scripts/holesky/vote_sr_v2_holesky.py @@ -73,7 +73,7 @@ # SR PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] -MAX_DEPOSITS_PER_BLOCK = [50, 50, 50] +MAX_DEPOSITS_PER_BLOCK = [150, 50, 50] MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] NOR_VERSION = ["2", "0", "0"] SDVT_VERSION = ["2", "0", "0"] @@ -82,14 +82,14 @@ VEBO_CONSENSUS_VERSION = 2 # CSM -CS_MODULE_NAME = "CommunityStaking" -CS_STAKE_SHARE_LIMIT = 2000 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 -CS_STAKING_MODULE_FEE = 800 -CS_TREASURY_FEE = 200 +CS_MODULE_NAME = "Community Staking" +CS_STAKE_SHARE_LIMIT = 1000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2000 +CS_STAKING_MODULE_FEE = 700 +CS_TREASURY_FEE = 300 CS_MAX_DEPOSITS_PER_BLOCK = 30 CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 58050 +CS_ORACLE_INITIAL_EPOCH = 63055 EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0x07696EA8A5b53C3E35d9cce10cc62c6c79C4691D" diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py index 5c4522084..7448f8da4 100644 --- a/tests/test_vote_sr_v2_holesky.py +++ b/tests/test_vote_sr_v2_holesky.py @@ -63,7 +63,7 @@ class StakingModuleItem(NamedTuple): # new added fields CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 -CURATED_MAX_DEPOSITS_PER_BLOCK = 50 +CURATED_MAX_DEPOSITS_PER_BLOCK = 150 CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 SDVT_MAX_DEPOSITS_PER_BLOCK = 50 @@ -119,14 +119,14 @@ class StakingModuleItem(NamedTuple): } ) -CS_MODULE_NAME = "CommunityStaking" -CS_STAKE_SHARE_LIMIT = 2000 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 -CS_STAKING_MODULE_FEE = 800 -CS_TREASURY_FEE = 200 +CS_MODULE_NAME = "Community Staking" +CS_STAKE_SHARE_LIMIT = 1000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2000 +CS_STAKING_MODULE_FEE = 700 +CS_TREASURY_FEE = 300 CS_MAX_DEPOSITS_PER_BLOCK = 30 CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 58050 +CS_ORACLE_INITIAL_EPOCH = 63055 CSM_AFTER_VOTE = { "id": 4, From 653b511c0709a3c949db0f64b3bcef10a0c91afc Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 28 Jun 2024 09:06:03 +0200 Subject: [PATCH 049/220] test: update limits --- configs/config_mainnet.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index bb75d4f25..a0fa10b2c 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -172,14 +172,14 @@ # OracleReportSanityChecker ORACLE_REPORT_SANITY_CHECKER = "0x9305c1Dbfe22c12c66339184C0025d7006f0f1cC" -APPEARED_VALIDATORS_PER_DAY_LIMIT = 9000 -EXITED_VALIDATORS_PER_DAY_LIMIT = 43200 +APPEARED_VALIDATORS_PER_DAY_LIMIT = 43200 +EXITED_VALIDATORS_PER_DAY_LIMIT = 9000 ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT = 500 # 5% ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT = 50 # 0.5% MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT = 600 -MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT = 4 -MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT = 50 +MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT = 8 +MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT = 62 REQUEST_TIMESTAMP_MARGIN = 7680 # 2 hours rounded to epoch length MAX_POSITIVE_TOKEN_REBASE = 750000 From 41569664290b54dac0eac7bbbf340e97b7e1c39a Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 28 Jun 2024 09:09:29 +0200 Subject: [PATCH 050/220] test: fix sdvt module version --- configs/config_mainnet.py | 1 + tests/acceptance/test_simple_dvt_module.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index a0fa10b2c..80a17acaa 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -157,6 +157,7 @@ # bytes32("curated-onchain-v1") "0x637572617465642d6f6e636861696e2d76310000000000000000000000000000" ) +SIMPLE_DVT_VERSION = 3 # OracleDaemonConfig ORACLE_DAEMON_CONFIG = "0xbf05A929c3D7885a6aeAd833a992dA6E5ac23b09" diff --git a/tests/acceptance/test_simple_dvt_module.py b/tests/acceptance/test_simple_dvt_module.py index 000676273..6547a0291 100644 --- a/tests/acceptance/test_simple_dvt_module.py +++ b/tests/acceptance/test_simple_dvt_module.py @@ -1,6 +1,7 @@ import pytest from brownie import ZERO_ADDRESS, interface, web3, reverts # type: ignore +from configs.config_mainnet import SIMPLE_DVT_VERSION from utils.config import ( contracts, SIMPLE_DVT, @@ -53,7 +54,7 @@ def test_role_keccaks(contract): def test_versioned(contract): - assert contract.getContractVersion() == 2 + assert contract.getContractVersion() == SIMPLE_DVT_VERSION def test_initialize(contract): From 2e71524193828b9f77e64cd6609236c970197086 Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 28 Jun 2024 09:10:38 +0200 Subject: [PATCH 051/220] reff: rename expected limits --- tests/acceptance/test_oracle_report_sanity_checker.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/acceptance/test_oracle_report_sanity_checker.py b/tests/acceptance/test_oracle_report_sanity_checker.py index fa8c4bd5c..03ce248bc 100644 --- a/tests/acceptance/test_oracle_report_sanity_checker.py +++ b/tests/acceptance/test_oracle_report_sanity_checker.py @@ -17,7 +17,7 @@ ) # Source of truth: https://hackmd.io/pdix1r4yR46fXUqiHaNKyw?view -report_limits = { +expected_report_limits = { "exitedValidatorsPerDayLimit": EXITED_VALIDATORS_PER_DAY_LIMIT, "oneOffCLBalanceDecreaseBPLimit": ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT, "annualBalanceIncreaseBPLimit": ANNUAL_BALANCE_INCREASE_BP_LIMIT, @@ -41,6 +41,7 @@ def test_links(contract): def test_limits(contract): - assert contract.getMaxPositiveTokenRebase() == report_limits["maxPositiveTokenRebase"] + assert contract.getMaxPositiveTokenRebase() == expected_report_limits["maxPositiveTokenRebase"] + limits = contract.getOracleReportLimits() - assert dict(zip(report_limits.keys(), contract.getOracleReportLimits())) == report_limits + assert dict(zip(expected_report_limits.keys(), limits)) == expected_report_limits From 465992cbb9b2e7ee31a3b01be2bb4004915c7c0b Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 28 Jun 2024 09:18:09 +0200 Subject: [PATCH 052/220] test: fix staking router version --- configs/config_mainnet.py | 1 + tests/acceptance/test_simple_dvt_module.py | 2 +- tests/acceptance/test_staking_router.py | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 80a17acaa..3b5c06edc 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -256,6 +256,7 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" STAKING_ROUTER_IMPL = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" # set address here after SR V2 deploy +STAKING_ROUTER_VERSION = 2 # Not a precise but still some estimation of the fees. Assume here that both modules are filled # SR_MODULES_FEE = curated_module_fee * (100% - sdvt_module_share) + sdvt_module_fee * sdvt_module_share diff --git a/tests/acceptance/test_simple_dvt_module.py b/tests/acceptance/test_simple_dvt_module.py index 6547a0291..1775ae7a3 100644 --- a/tests/acceptance/test_simple_dvt_module.py +++ b/tests/acceptance/test_simple_dvt_module.py @@ -1,11 +1,11 @@ import pytest from brownie import ZERO_ADDRESS, interface, web3, reverts # type: ignore -from configs.config_mainnet import SIMPLE_DVT_VERSION from utils.config import ( contracts, SIMPLE_DVT, SIMPLE_DVT_IMPL, + SIMPLE_DVT_VERSION, SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_MODULE_STUCK_PENALTY_DELAY, SIMPLE_DVT_MODULE_TYPE, diff --git a/tests/acceptance/test_staking_router.py b/tests/acceptance/test_staking_router.py index 97214d1fa..b0a6c0a3d 100644 --- a/tests/acceptance/test_staking_router.py +++ b/tests/acceptance/test_staking_router.py @@ -5,6 +5,7 @@ contracts, STAKING_ROUTER, STAKING_ROUTER_IMPL, + STAKING_ROUTER_VERSION, CHAIN_DEPOSIT_CONTRACT, WITHDRAWAL_VAULT, SR_MODULES_FEE_BP, @@ -44,7 +45,7 @@ def test_links(contract): def test_versioned(contract): - assert contract.getContractVersion() == 1 + assert contract.getContractVersion() == STAKING_ROUTER_VERSION def test_initialize(contract): From cfd1e5dcfb6821d90c615409da25857ea687f1a3 Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 28 Jun 2024 09:30:18 +0200 Subject: [PATCH 053/220] test: rename targetShare to stakeShareLimit --- tests/acceptance/test_staking_router.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/test_staking_router.py b/tests/acceptance/test_staking_router.py index b0a6c0a3d..1d886ab65 100644 --- a/tests/acceptance/test_staking_router.py +++ b/tests/acceptance/test_staking_router.py @@ -97,7 +97,7 @@ def test_staking_modules(contract): assert curated_module["stakingModuleAddress"] == contracts.node_operators_registry assert curated_module["stakingModuleFee"] == CURATED_STAKING_MODULE_MODULE_FEE_BP assert curated_module["treasuryFee"] == CURATED_STAKING_MODULE_TREASURY_FEE_BP - assert curated_module["targetShare"] == CURATED_STAKING_MODULE_TARGET_SHARE_BP + assert curated_module["stakeShareLimit"] == CURATED_STAKING_MODULE_TARGET_SHARE_BP assert curated_module["status"] == 0 assert curated_module["name"] == CURATED_STAKING_MODULE_NAME assert curated_module["lastDepositAt"] >= 1679672628 @@ -109,7 +109,7 @@ def test_staking_modules(contract): assert simple_dvt_module["stakingModuleAddress"] == contracts.simple_dvt assert simple_dvt_module["stakingModuleFee"] == SIMPLE_DVT_MODULE_MODULE_FEE_BP assert simple_dvt_module["treasuryFee"] == SIMPLE_DVT_MODULE_TREASURY_FEE_BP - assert simple_dvt_module["targetShare"] == SIMPLE_DVT_MODULE_TARGET_SHARE_BP + assert simple_dvt_module["stakeShareLimit"] == SIMPLE_DVT_MODULE_TARGET_SHARE_BP assert simple_dvt_module["status"] == 0 assert simple_dvt_module["name"] == SIMPLE_DVT_MODULE_NAME assert simple_dvt_module["lastDepositAt"] > 0 From 504f1361d072d7a33b6d2fc19fe11088fa841db2 Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 28 Jun 2024 09:46:28 +0200 Subject: [PATCH 054/220] test: update vebo consensus version --- configs/config_mainnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 3b5c06edc..25b2bdebe 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -220,7 +220,7 @@ HASH_CONSENSUS_FOR_VEBO = "0x7FaDB6358950c5fAA66Cb5EB8eE5147De3df355a" VEBO_EPOCHS_PER_FRAME = 75 VEBO_FAST_LANE_LENGTH_SLOTS = 100 -VEBO_CONSENSUS_VERSION = 1 +VEBO_CONSENSUS_VERSION = 2 # AccountingOracle and ValidatorsExitBusOracle From 907d7ae8487df95df4eb2b0fd4ae1e82630da4f3 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 1 Jul 2024 10:52:41 +0200 Subject: [PATCH 055/220] test: increase diff --- .../test_accounting_oracle_extra_data_full_items.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index a9ee3a8fb..9b37c63a9 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -161,7 +161,7 @@ def test_extra_data_full_items( nor_penalty_shares += rewards_after // 2 if nor_penalty_shares > 0: - assert almostEqWithDiff(sum(e['amountOfShares'] for e in nor_distribute_reward_tx.events["StETHBurnRequested"]), nor_penalty_shares, 50) + assert almostEqWithDiff(sum(e['amountOfShares'] for e in nor_distribute_reward_tx.events["StETHBurnRequested"]), nor_penalty_shares, 100) # Check SDVT exited sdvt_penalty_shares = 0 @@ -187,7 +187,7 @@ def test_extra_data_full_items( if sdvt_penalty_shares > 0: # TODO: Fix below check when contains other penalized node operators - assert almostEqWithDiff(sum(e['amountOfShares'] for e in sdvt_distribute_reward_tx.events["StETHBurnRequested"]), sdvt_penalty_shares, 50) + assert almostEqWithDiff(sum(e['amountOfShares'] for e in sdvt_distribute_reward_tx.events["StETHBurnRequested"]), sdvt_penalty_shares, 100) ############################################ # HELPER FUNCTIONS From 2178362dbc75a73eecacc8ced010bed0a073de4e Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 1 Jul 2024 11:35:43 +0200 Subject: [PATCH 056/220] test: set address balance --- tests/regression/test_accounting.py | 7 ++----- utils/balance.py | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 utils/balance.py diff --git a/tests/regression/test_accounting.py b/tests/regression/test_accounting.py index 95942ee36..0346494e1 100644 --- a/tests/regression/test_accounting.py +++ b/tests/regression/test_accounting.py @@ -6,6 +6,7 @@ from brownie.network.account import Account from web3 import Web3 +from utils.balance import set_balance from utils.evm_script import encode_error from tests.conftest import Helpers from utils.config import contracts @@ -1132,11 +1133,7 @@ def _round_to_gwei(amount: int) -> int: def _drain_eth(address: str): """Drain ETH from address""" - accounts.at(address, force=True).transfer( - Account(ZERO_ADDRESS), - eth_balance(address), - silent=True, - ) + set_balance(address, 0) assert eth_balance(address) == 0, f"Expected account {address} to be empty" diff --git a/utils/balance.py b/utils/balance.py new file mode 100644 index 000000000..82f57a65e --- /dev/null +++ b/utils/balance.py @@ -0,0 +1,22 @@ +from brownie import accounts, web3 +from utils.test.helpers import ETH + +def set_balance(address, balanceInEth): + account = accounts.at(address, force=True) + balance = ETH(balanceInEth) + + if account.balance() != balance: + # try Ganache + try: + web3.provider.make_request("evm_setAccountBalance", [address, hex(balance)]) + except: + pass + if account.balance() != balance: + # try Anvil + try: + web3.provider.make_request("anvil_setBalance", [address, hex(balance)]) + except: + pass + + assert account.balance() == ETH(balanceInEth) + return account From cef713ca3be44a8b62d8adc4687527eaeebe62d1 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 1 Jul 2024 11:37:55 +0200 Subject: [PATCH 057/220] refactor: use set_balance for setting stranger account balance --- tests/conftest.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c84407360..631a48815 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,6 +9,7 @@ from brownie.network import state from brownie.network.contract import Contract +from utils.balance import set_balance from utils.evm_script import EMPTY_CALLSCRIPT from utils.config import contracts, network_name, MAINNET_VOTE_DURATION @@ -46,22 +47,8 @@ def ldo_holder(accounts): @pytest.fixture(scope="function") -def stranger(accounts): - stranger = accounts.at("0x98eC059dC3aDFbdd63429454aeB0C990fbA4a124", force=True) - if(stranger.balance() != ETH(100000)): - # try Ganache - try: - web3.provider.make_request("evm_setAccountBalance", [stranger.address, "0x152D02C7E14AF6800000"]) - except: - pass - if(stranger.balance() != ETH(100000)): - # try Anvil - try: - web3.provider.make_request("anvil_setBalance", [stranger.address, "0x152D02C7E14AF6800000"]) - except: - pass - assert stranger.balance() == ETH(100000) - return stranger +def stranger(): + return set_balance("0x98eC059dC3aDFbdd63429454aeB0C990fbA4a124", 100000) @pytest.fixture(scope="module") From 35878b5727a8629944bae7af78bfe875eed0f17a Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 1 Jul 2024 11:39:42 +0200 Subject: [PATCH 058/220] test: add middleware for updating account balance if insufficient --- tests/conftest.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 631a48815..98c60345c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,6 +18,8 @@ from utils.txs.deploy import deploy_from_prepared_tx from utils.test.helpers import ETH +from functools import wraps + ENV_OMNIBUS_BYPASS_EVENTS_DECODING = "OMNIBUS_BYPASS_EVENTS_DECODING" ENV_PARSE_EVENTS_FROM_LOCAL_ABI = "PARSE_EVENTS_FROM_LOCAL_ABI" ENV_OMNIBUS_VOTE_IDS = "OMNIBUS_VOTE_IDS" @@ -234,3 +236,24 @@ def parse_events_from_local_abi(): # See https://eth-brownie.readthedocs.io/en/stable/api-network.html?highlight=_add_contract#brownie.network.state._add_contract # Added contract will resolve from address during state._find_contract without a request to Etherscan state._add_contract(contract) + + +@pytest.fixture(scope="session", autouse=True) +def add_balance_check_middleware(): + web3.middleware_onion.add(balance_check_middleware, name='balance_check') + +def ensure_balance(address): + if web3.eth.get_balance(address) < ETH(1): + set_balance(address, 1000000) + +def balance_check_middleware(make_request, web3): + @wraps(make_request) + def middleware(method, params): + if method in ["eth_sendTransaction", "eth_sendRawTransaction"]: + transaction = params[0] + from_address = transaction.get('from') + if from_address: + ensure_balance(from_address) + + return make_request(method, params) + return middleware From d2c481830d69ef31c2a58264137fc58b7d5c6af3 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 1 Jul 2024 13:28:41 +0200 Subject: [PATCH 059/220] test: fix happy path, include transaction cost --- tests/regression/test_all_round_happy_path.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/regression/test_all_round_happy_path.py b/tests/regression/test_all_round_happy_path.py index 6996c8653..6c5830fa3 100644 --- a/tests/regression/test_all_round_happy_path.py +++ b/tests/regression/test_all_round_happy_path.py @@ -8,6 +8,11 @@ from utils.test.simple_dvt_helpers import fill_simple_dvt_ops_vetted_keys +def transaction_cost(tx): + gas_used = tx.gas_used + gas_price = tx.gas_price + return gas_used * gas_price + def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): print(stranger, stranger.balance()) amount = ETH(100) @@ -30,14 +35,15 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): contracts.lido.approve(contracts.withdrawal_queue.address, 1000, {"from": steth_holder}) contracts.withdrawal_queue.requestWithdrawals([1000], steth_holder, {"from": steth_holder}) + # ensure SimpleDVT has some keys to deposit + fill_simple_dvt_ops_vetted_keys(stranger, 3, 5) + print(stranger, stranger.balance()) steth_balance_before_submit = contracts.lido.balanceOf(stranger) eth_balance_before_submit = stranger.balance() assert steth_balance_before_submit == 0 - # ensure SimpleDVT has some keys to deposit - fill_simple_dvt_ops_vetted_keys(stranger, 3, 5) # Submitting ETH stakeLimitInfo = contracts.lido.getStakeLimitFullInfo() @@ -57,6 +63,7 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): submit_tx = contracts.lido.submit(ZERO_ADDRESS, {"from": stranger, "amount": amount}) + print("block after submit: ", chain.height) steth_balance_after_submit = contracts.lido.balanceOf(stranger) @@ -66,7 +73,7 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): print("block after view: ", chain.height) assert almostEqEth(steth_balance_after_submit, steth_balance_before_submit + amount) - assert eth_balance_before_submit == stranger.balance() + amount + assert almostEqEth(eth_balance_before_submit, stranger.balance() + amount + transaction_cost(submit_tx)) shares_to_be_minted = contracts.lido.getSharesByPooledEth(amount) @@ -329,7 +336,7 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): assert transfer_event["to"] == ZERO_ADDRESS assert transfer_event["tokenId"] == request_ids[0] - assert eth_balance_before_withdrawal == stranger.balance() - amount_with_rewards + assert almostEqEth(eth_balance_before_withdrawal, stranger.balance() - amount_with_rewards + transaction_cost(claim_tx)) assert ( locked_ether_amount_after_finalization == contracts.withdrawal_queue.getLockedEtherAmount() + amount_with_rewards From f425a6a5d167b77e4900fa8aee1c3be004450819 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 1 Jul 2024 17:56:15 +0200 Subject: [PATCH 060/220] test: fix test_el_rewards --- tests/regression/test_all_round_happy_path.py | 7 +------ tests/regression/test_el_rewards.py | 4 ++-- utils/test/tx_cost_helper.py | 4 ++++ 3 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 utils/test/tx_cost_helper.py diff --git a/tests/regression/test_all_round_happy_path.py b/tests/regression/test_all_round_happy_path.py index 6c5830fa3..8f9312e23 100644 --- a/tests/regression/test_all_round_happy_path.py +++ b/tests/regression/test_all_round_happy_path.py @@ -6,12 +6,7 @@ from utils.test.helpers import ETH, almostEqEth from utils.config import contracts from utils.test.simple_dvt_helpers import fill_simple_dvt_ops_vetted_keys - - -def transaction_cost(tx): - gas_used = tx.gas_used - gas_price = tx.gas_price - return gas_used * gas_price +from utils.test.tx_cost_helper import transaction_cost def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): print(stranger, stranger.balance()) diff --git a/tests/regression/test_el_rewards.py b/tests/regression/test_el_rewards.py index 259820239..da5678fbf 100644 --- a/tests/regression/test_el_rewards.py +++ b/tests/regression/test_el_rewards.py @@ -7,7 +7,7 @@ from brownie.network import chain from utils.config import contracts - +from utils.test.tx_cost_helper import transaction_cost TOTAL_BASIS_POINTS = 10000 EL_REWARDS_FEE_WITHDRAWAL_LIMIT = 2 @@ -53,7 +53,7 @@ def test_receive_el_rewards_permissions(stranger): assert_el_rewards_received_log(log=tx.logs[0], amount=reward_amount) assert contracts.lido.getTotalELRewardsCollected() - lido_el_rewards_collected_before == reward_amount - assert contracts.execution_layer_rewards_vault.balance() == (el_balance_after - reward_amount) + assert contracts.execution_layer_rewards_vault.balance() == (el_balance_after - reward_amount - transaction_cost(tx)) assert contracts.lido.balance() == lido_eth_balance_before + reward_amount diff --git a/utils/test/tx_cost_helper.py b/utils/test/tx_cost_helper.py new file mode 100644 index 000000000..630d2f634 --- /dev/null +++ b/utils/test/tx_cost_helper.py @@ -0,0 +1,4 @@ +def transaction_cost(tx): + gas_used = tx.gas_used + gas_price = tx.gas_price + return gas_used * gas_price From 3fe989eeedebb4b6fce3d9026bbce4374b0ba51f Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 2 Jul 2024 10:11:08 +0200 Subject: [PATCH 061/220] test: use AO consensus version constant --- utils/test/oracle_report_helpers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index 72cf670a6..0d17045f9 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -8,7 +8,7 @@ from eth_abi.abi import encode from hexbytes import HexBytes -from utils.config import contracts +from utils.config import (contracts, AO_CONSENSUS_VERSION) from utils.test.exit_bus_data import encode_data from utils.test.helpers import ETH, GWEI, eth_balance @@ -19,7 +19,6 @@ EXTRA_DATA_FORMAT_EMPTY = 0 EXTRA_DATA_FORMAT_LIST = 1 - @dataclass class AccountingReport: """Accounting oracle ReportData struct""" @@ -70,7 +69,7 @@ def prepare_accounting_report( simulatedShareRate, stakingModuleIdsWithNewlyExitedValidators=[], numExitedValidatorsByStakingModule=[], - consensusVersion=1, + consensusVersion=AO_CONSENSUS_VERSION, withdrawalFinalizationBatches=[], isBunkerMode=False, extraDataFormat=EXTRA_DATA_FORMAT_EMPTY, From f7b633b7e5f1bdd85e77bf0497cbddde469b2704 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 2 Jul 2024 10:30:55 +0200 Subject: [PATCH 062/220] test: fix test_node_operators_flow --- tests/regression/test_node_operators_flow.py | 2 +- utils/test/node_operators_helpers.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/regression/test_node_operators_flow.py b/tests/regression/test_node_operators_flow.py index 76995f285..6fcd4cbc5 100644 --- a/tests/regression/test_node_operators_flow.py +++ b/tests/regression/test_node_operators_flow.py @@ -93,7 +93,7 @@ def test_add_node_operator(nor, voting_eoa, reward_address, new_node_operator_id assert_node_operator_summaries( nor.getNodeOperatorSummary(new_node_operator_id), { - "isTargetLimitActive": False, + "targetLimitMode": 0, "targetValidatorsCount": 0, "stuckValidatorsCount": 0, "refundedValidatorsCount": 0, diff --git a/utils/test/node_operators_helpers.py b/utils/test/node_operators_helpers.py index 554125f7a..193c3fd4a 100644 --- a/utils/test/node_operators_helpers.py +++ b/utils/test/node_operators_helpers.py @@ -19,7 +19,7 @@ ] NODE_OPERATOR_SUMMARY_KEYS = [ - "isTargetLimitActive", + "targetLimitMode", "targetValidatorsCount", "stuckValidatorsCount", "refundedValidatorsCount", From eef09c34b96562df514ffcc253211cde4584cb63 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 2 Jul 2024 14:04:03 +0200 Subject: [PATCH 063/220] test: remove tests for deleted pause and resume contract methods --- tests/regression/test_pause_resume.py | 79 +++++------------------ tests/regression/test_pause_role_tests.py | 73 --------------------- 2 files changed, 17 insertions(+), 135 deletions(-) diff --git a/tests/regression/test_pause_resume.py b/tests/regression/test_pause_resume.py index 8cf498524..576b79b6a 100644 --- a/tests/regression/test_pause_resume.py +++ b/tests/regression/test_pause_resume.py @@ -66,32 +66,6 @@ def test_stop_resume_staking_lido_emit_events(self, helpers): assert not contracts.lido.isStakingPaused() assert not contracts.lido.isStopped() - def test_pause_resume_deposits_staking_module(self, helpers, stranger): - tx = contracts.staking_router.pauseStakingModule(1, {"from": contracts.deposit_security_module}) - helpers.assert_single_event_named( - "StakingModuleStatusSet", - tx, - { - "setBy": contracts.deposit_security_module, - "stakingModuleId": 1, - "status": StakingModuleStatus.DepositsPaused, - }, - ) - assert contracts.staking_router.getStakingModuleIsDepositsPaused(1) - - contracts.staking_router.grantRole( - web3.keccak(text="STAKING_MODULE_RESUME_ROLE"), - stranger, - {"from": contracts.agent}, - ) - tx = contracts.staking_router.resumeStakingModule(1, {"from": stranger}) - helpers.assert_single_event_named( - "StakingModuleStatusSet", - tx, - {"setBy": stranger, "stakingModuleId": 1, "status": StakingModuleStatus.Active}, - ) - assert contracts.staking_router.getStakingModuleIsActive(1) - def test_stop_staking_module(self, helpers, stranger): contracts.staking_router.grantRole( web3.keccak(text="STAKING_MODULE_MANAGE_ROLE"), @@ -161,38 +135,6 @@ def test_revert_second_stop_resume(self): with brownie.reverts("CONTRACT_IS_ACTIVE"): contracts.lido.resume({"from": contracts.voting}) - @pytest.mark.skip( - reason="Second call of pause/resume staking is not reverted right now." - "It maybe should be fixed in the future to be consistent, " - "there's not a real problem with it." - ) - def test_revert_second_pause_resume_staking(self): - contracts.lido.pauseStaking({"from": contracts.voting}) - - with brownie.reverts(""): - contracts.lido.pauseStaking({"from": contracts.voting}) - - contracts.lido.resumeStaking({"from": contracts.voting}) - - with brownie.reverts(""): - contracts.lido.resumeStaking({"from": contracts.voting}) - - def test_revert_second_pause_resume_staking_module(self, stranger): - contracts.staking_router.pauseStakingModule(1, {"from": contracts.deposit_security_module}) - - with brownie.reverts(encode_error("StakingModuleNotActive()")): - contracts.staking_router.pauseStakingModule(1, {"from": contracts.deposit_security_module}) - - contracts.staking_router.grantRole( - web3.keccak(text="STAKING_MODULE_RESUME_ROLE"), - stranger, - {"from": contracts.agent}, - ) - contracts.staking_router.resumeStakingModule(1, {"from": stranger}) - - with brownie.reverts(encode_error("StakingModuleNotPaused()")): - contracts.staking_router.resumeStakingModule(1, {"from": stranger}) - def test_revert_second_stop_staking_module(self, helpers, stranger): contracts.staking_router.grantRole( web3.keccak(text="STAKING_MODULE_MANAGE_ROLE"), @@ -294,15 +236,28 @@ def test_paused_staking_can_report(): # Staking module tests -def test_paused_staking_module_cant_stake(): - contracts.staking_router.pauseStakingModule(1, {"from": contracts.deposit_security_module}) +def test_paused_staking_module_cant_stake(stranger): + contracts.staking_router.grantRole( + web3.keccak(text="STAKING_MODULE_MANAGE_ROLE"), + stranger, + {"from": contracts.agent}, + ) + contracts.staking_router.setStakingModuleStatus(1, StakingModuleStatus.DepositsPaused, {"from": stranger}) + with brownie.reverts(encode_error("StakingModuleNotActive()")): contracts.lido.deposit(1, 1, "0x", {"from": contracts.deposit_security_module}), -def test_paused_staking_module_can_reward(burner: Contract): +def test_paused_staking_module_can_reward(burner: Contract, stranger): _, module_address, *_ = contracts.staking_router.getStakingModule(1) - contracts.staking_router.pauseStakingModule(1, {"from": contracts.deposit_security_module}) + + contracts.staking_router.grantRole( + web3.keccak(text="STAKING_MODULE_MANAGE_ROLE"), + stranger, + {"from": contracts.agent}, + ) + contracts.staking_router.setStakingModuleStatus(1, StakingModuleStatus.DepositsPaused, {"from": stranger}) + (report_tx, _) = oracle_report() print(report_tx.events["Transfer"]) module_index = 0 diff --git a/tests/regression/test_pause_role_tests.py b/tests/regression/test_pause_role_tests.py index 2040ff70e..399b54982 100644 --- a/tests/regression/test_pause_role_tests.py +++ b/tests/regression/test_pause_role_tests.py @@ -19,21 +19,6 @@ def resume_lido(): if contracts.lido.isStopped(): contracts.lido.resume({"from": contracts.voting}) -@pytest.fixture(scope="function") -def pause_staking_module(): - if not contracts.staking_router.getStakingModuleIsDepositsPaused(1): - contracts.staking_router.pauseStakingModule(1, {"from": contracts.deposit_security_module}) - -@pytest.fixture(scope="function") -def resume_staking_module(): - if contracts.staking_router.getStakingModuleIsDepositsPaused(1): - contracts.staking_router.grantRole( - web3.keccak(text="STAKING_MODULE_RESUME_ROLE"), - contracts.agent, - {"from": contracts.agent}, - ) - contracts.staking_router.resumeStakingModule(1, {"from": contracts.deposit_security_module}) - @pytest.fixture(scope="function") def pause_withdrawal_queue(): inf = contracts.withdrawal_queue.PAUSE_INFINITELY() @@ -127,65 +112,7 @@ def test_pause_role_can_pause(stranger): contracts.lido.stop({"from": stranger}) assert contracts.lido.isStopped() -@pytest.mark.usefixtures("resume_staking_module") -def test_staking_module_pause_role_can_pause(stranger): - with reverts(): - contracts.staking_router.pauseStakingModule(1, {"from": stranger}) - - stranger_has_role = partial(has_role, entity=stranger, contract=contracts.staking_router) - assert not stranger_has_role(role="STAKING_MODULE_PAUSE_ROLE") - - contracts.staking_router.grantRole( - web3.keccak(text="STAKING_MODULE_PAUSE_ROLE"), - stranger, - {"from": contracts.agent}, - ) - assert stranger_has_role(role="STAKING_MODULE_PAUSE_ROLE") - - contracts.staking_router.pauseStakingModule(1, {"from": stranger}) - assert contracts.staking_router.getStakingModuleIsDepositsPaused(1) -@pytest.mark.usefixtures("pause_staking_module") -def test_staking_module_pause_role_cant_resume(stranger): - contracts.staking_router.grantRole( - web3.keccak(text="STAKING_MODULE_PAUSE_ROLE"), - stranger, - {"from": contracts.agent}, - ) - - assert contracts.staking_router.getStakingModuleIsDepositsPaused(1) - with reverts(): - contracts.staking_router.resumeStakingModule(1, {"from": stranger}) - -@pytest.mark.usefixtures("pause_staking_module") -def test_staking_module_resume_role_can_resume(stranger): - with reverts(): - contracts.staking_router.resumeStakingModule(1, {"from": stranger}) - - stranger_has_role = partial(has_role, entity=stranger, contract=contracts.staking_router) - assert not stranger_has_role(role="STAKING_MODULE_RESUME_ROLE") - - contracts.staking_router.grantRole( - web3.keccak(text="STAKING_MODULE_RESUME_ROLE"), - stranger, - {"from": contracts.agent}, - ) - assert stranger_has_role(role="STAKING_MODULE_RESUME_ROLE") - assert contracts.staking_router.getStakingModuleIsDepositsPaused(1) - contracts.staking_router.resumeStakingModule(1, {"from": stranger}) - assert contracts.staking_router.getStakingModuleIsActive(1) - -@pytest.mark.usefixtures("resume_staking_module") -def test_staking_module_resume_role_cant_pause(stranger): - contracts.staking_router.grantRole( - web3.keccak(text="STAKING_MODULE_RESUME_ROLE"), - stranger, - {"from": contracts.agent}, - ) - - assert contracts.staking_router.getStakingModuleIsActive(1) - with reverts(): - contracts.staking_router.pauseStakingModule(1, {"from": stranger}) @pytest.mark.usefixtures("resume_withdrawal_queue") def test_withdrawal_queue_pause_role_can_pause(stranger): From 526e15c6dca69195d8fc4a9e1ecd84d07dd02747 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Tue, 2 Jul 2024 16:33:44 +0400 Subject: [PATCH 064/220] fix: removed STAKING_MODULE_MANAGE_ROLE revoke/grant --- scripts/mainnet/vote_sr_v2_mainnet.py | 57 +++++++-------------------- 1 file changed, 14 insertions(+), 43 deletions(-) diff --git a/scripts/mainnet/vote_sr_v2_mainnet.py b/scripts/mainnet/vote_sr_v2_mainnet.py index 558240ec2..d4b9c527a 100644 --- a/scripts/mainnet/vote_sr_v2_mainnet.py +++ b/scripts/mainnet/vote_sr_v2_mainnet.py @@ -20,15 +20,13 @@ CSM -18. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE -19. Add staking module -20. Grant request burn role to CSAccounting contract -21. Grant resume role to agent -22. Resume staking module -23. Revoke resume role from agent -24. Update initial epoch -25. Add CS settle EL stealing factory to ET -26. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT} +18. Add staking module +19. Grant request burn role to CSAccounting contract +20. Grant resume role to agent +21. Resume staking module +22. Revoke resume role from agent +23. Update initial epoch +24. Add CS settle EL stealing factory to ET """ import time @@ -150,11 +148,8 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T nor_repo = contracts.nor_app_repo.address simple_dvt_repo = contracts.simple_dvt_app_repo.address - sandbox_repo = contracts.sandbox_repo.address - nor_uri = get_repo_uri(nor_repo) simple_dvt_uri = get_repo_uri(simple_dvt_repo) - sandbox_uri = get_repo_uri(sandbox_repo) vote_desc_items, call_script_items = zip( # @@ -272,19 +267,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # CSM # ( - "18. Grant staking module manage role to agent STAKING_MODULE_MANAGE_ROLE", - agent_forward( - [ - encode_oz_grant_role( - contract=contracts.staking_router, - role_name="STAKING_MODULE_MANAGE_ROLE", - grant_to=contracts.agent, - ) - ] - ), - ), - ( - "19. Add staking module", + "18. Add staking module", agent_forward( [ ( @@ -304,7 +287,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "20. Grant request burn role to CSAccounting contract", + "19. Grant request burn role to CSAccounting contract", agent_forward( [ encode_oz_grant_role( @@ -316,7 +299,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "21. Grant resume role to agent", + "20. Grant resume role to agent", agent_forward( [ encode_oz_grant_role( @@ -328,11 +311,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "22. Resume staking module", + "21. Resume staking module", agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), ), ( - "23. Revoke resume role from agent", + "22. Revoke resume role from agent", agent_forward( [ encode_oz_revoke_role( @@ -344,7 +327,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "24. Update initial epoch", + "23. Update initial epoch", agent_forward( [ ( @@ -355,24 +338,12 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), # ( - # "25. Add CS settle EL stealing factory to ET", + # "24. Add CS settle EL stealing factory to ET", # add_evmscript_factory( # factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, # permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), # ), # ), - ( - "26. Revoke STAKING_MODULE_MANAGE_ROLE from agent ${AGENT}", - agent_forward( - [ - encode_oz_revoke_role( - contract=contracts.staking_router, - role_name="STAKING_MODULE_MANAGE_ROLE", - revoke_from=contracts.agent, - ) - ] - ), - ), ) vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) From e3c3d6a8c87536a0991eced8883f7ed9cc6efaf7 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 2 Jul 2024 15:24:23 +0200 Subject: [PATCH 065/220] test: sanity checker remove agent from roles --- tests/regression/test_permissions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/regression/test_permissions.py b/tests/regression/test_permissions.py index 019686d14..037c4bd9e 100644 --- a/tests/regression/test_permissions.py +++ b/tests/regression/test_permissions.py @@ -166,8 +166,8 @@ def protocol_permissions(): "ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE": [], "SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE": [], "MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT_ROLE": [], - "MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE": [contracts.agent], - "MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE": [contracts.agent], + "MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE": [], + "MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE": [], "REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE": [], "MAX_POSITIVE_TOKEN_REBASE_MANAGER_ROLE": [], }, From 1ffd721580f597d3c03236bc59c3c4bc03011db7 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 2 Jul 2024 17:16:17 +0200 Subject: [PATCH 066/220] test: fix sdvt happy path --- .../test_sdvt_rewards_happy_path.py | 19 +++++++------ utils/test/staking_router_helpers.py | 28 +++++++++++-------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/tests/regression/test_sdvt_rewards_happy_path.py b/tests/regression/test_sdvt_rewards_happy_path.py index 78fdd19e0..4f8f7f6f0 100644 --- a/tests/regression/test_sdvt_rewards_happy_path.py +++ b/tests/regression/test_sdvt_rewards_happy_path.py @@ -4,6 +4,7 @@ from utils.config import contracts from utils.test.deposits_helpers import fill_deposit_buffer +from utils.test.node_operators_helpers import distribute_reward from utils.test.reward_wrapper_helpers import deploy_reward_wrapper, wrap_and_split_rewards from utils.test.split_helpers import ( deploy_split_wallet, @@ -12,7 +13,7 @@ split_and_withdraw_wsteth_rewards, ) from utils.test.simple_dvt_helpers import simple_dvt_add_keys, simple_dvt_vet_keys, simple_dvt_add_node_operators -from utils.test.staking_router_helpers import pause_staking_module +from utils.test.staking_router_helpers import StakingModuleStatus, set_staking_module_status from utils.test.oracle_report_helpers import oracle_report @@ -56,7 +57,7 @@ def test_sdvt_module_connected_to_router(): # full happy path test -def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participants, reward_wrapper): +def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participants, reward_wrapper, sdvt, stranger): """ Test happy path of rewards distribution Test adding new cluster to simple dvt module, depositing to simple dvt module, distributing and claiming rewards @@ -64,7 +65,7 @@ def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participa simple_dvt, staking_router = contracts.simple_dvt, contracts.staking_router lido, deposit_security_module = contracts.lido, contracts.deposit_security_module - stranger = cluster_participants[0] + new_dvt_operator = cluster_participants[0] new_cluster_name = "new cluster" new_manager_address = "0x1110000000000000000000000000000011111111" @@ -73,7 +74,7 @@ def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participa # add operator to simple dvt module input_params = [(new_cluster_name, new_reward_address, new_manager_address)] (node_operators_count_before, node_operator_count_after) = simple_dvt_add_node_operators( - simple_dvt, stranger, input_params + simple_dvt, new_dvt_operator, input_params ) operator_id = node_operator_count_after - 1 assert node_operator_count_after == node_operators_count_before + len(input_params) @@ -82,14 +83,15 @@ def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participa simple_dvt_add_keys(simple_dvt, operator_id, 10) # vet operator keys - simple_dvt_vet_keys(operator_id, stranger) + simple_dvt_vet_keys(operator_id, new_dvt_operator) + # pause deposit to all modules except simple dvt # to be sure that all deposits go to simple dvt modules = staking_router.getStakingModules() for module in modules: if module[0] != simple_dvt_module_id: - pause_staking_module(module[0]) + set_staking_module_status(module[0], StakingModuleStatus.Stopped) # fill the deposit buffer deposits_count = 10 @@ -111,13 +113,14 @@ def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participa # oracle report oracle_report(cl_diff=ETH(100)) + distribute_reward(contracts.simple_dvt, stranger.address) cluster_rewards_after_report = lido.balanceOf(new_reward_address) # check that cluster reward address balance increased assert cluster_rewards_after_report > 0 # wrap rewards and split between dvt provider and split wallet - wrap_and_split_rewards(reward_wrapper, stranger) + wrap_and_split_rewards(reward_wrapper, new_dvt_operator) # split wsteth rewards between participants and withdraw split_and_withdraw_wsteth_rewards( @@ -125,5 +128,5 @@ def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participa cluster_participants, get_split_percent_allocation(len(cluster_participants), get_split_percentage_scale()), get_split_percentage_scale(), - stranger, + new_dvt_operator, ) diff --git a/utils/test/staking_router_helpers.py b/utils/test/staking_router_helpers.py index cfd421f20..a77342dac 100644 --- a/utils/test/staking_router_helpers.py +++ b/utils/test/staking_router_helpers.py @@ -1,17 +1,21 @@ +from brownie import web3 from utils.config import contracts -from enum import Enum +from enum import IntEnum +class StakingModuleStatus(IntEnum): + Active = 0 + DepositsPaused = 1 + Stopped = 2 -class ModuleStatus(Enum): - ACTIVE = 0 - PAUSED = 1 - DISABLED = 2 +new_staking_module_manager_address = "0xB871BB28d7e6Be4A373ed7a2DD6733a7423dC089" +staking_router_manager_role = web3.keccak(text="STAKING_MODULE_MANAGE_ROLE") +def set_staking_module_status(module_id, staking_module_status: StakingModuleStatus): + if(not contracts.staking_router.hasRole(staking_router_manager_role, new_staking_module_manager_address)): + contracts.staking_router.grantRole( + staking_router_manager_role, + new_staking_module_manager_address, + {"from": contracts.agent}, + ) -def pause_staking_module(module_id): - staking_router, deposit_security_module = contracts.staking_router, contracts.deposit_security_module - - pause_tx = staking_router.pauseStakingModule(module_id, {"from": deposit_security_module}) - pause_event = pause_tx.events["StakingModuleStatusSet"] - assert pause_event["stakingModuleId"] == module_id - assert pause_event["status"] == ModuleStatus.PAUSED.value + contracts.staking_router.setStakingModuleStatus(module_id, staking_module_status, {"from": new_staking_module_manager_address}) From daf0884874ab440c9bca38224ee70407412eebdf Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 2 Jul 2024 18:05:45 +0200 Subject: [PATCH 067/220] test: fix staking module happy path --- .../test_staking_module_happy_path.py | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/tests/regression/test_staking_module_happy_path.py b/tests/regression/test_staking_module_happy_path.py index 9c1355d29..d7fcb53f1 100644 --- a/tests/regression/test_staking_module_happy_path.py +++ b/tests/regression/test_staking_module_happy_path.py @@ -11,7 +11,7 @@ oracle_report, ) from utils.config import contracts, STAKING_ROUTER, EASYTRACK_EVMSCRIPT_EXECUTOR -from utils.test.node_operators_helpers import node_operator_gindex +from utils.test.node_operators_helpers import distribute_reward, node_operator_gindex from utils.test.simple_dvt_helpers import fill_simple_dvt_ops_keys @@ -138,7 +138,7 @@ def parse_target_validators_count_changed(logs): return res -def module_happy_path(staking_module, extra_data_service, impersonated_voting, eth_whale): +def module_happy_path(staking_module, extra_data_service, impersonated_voting, eth_whale, stranger): nor_exited_count, _, _ = contracts.staking_router.getStakingModuleSummary(staking_module.module_id) # all_modules = contracts.staking_router.getStakingModules() @@ -188,7 +188,8 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e no3_balance_shares_before = shares_balance(no3_reward_address) # First report - base empty report - (report_tx, extra_report_tx) = oracle_report(exclude_vaults_balances=True) + (report_tx, extra_report_tx_list) = oracle_report(exclude_vaults_balances=True) + distribute_reward(staking_module, stranger.address) no1_balance_shares_after = shares_balance(no1_reward_address) no2_balance_shares_after = shares_balance(no2_reward_address) @@ -247,15 +248,16 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e deposit_and_check_keys(staking_module, no1_id, no2_id, no3_id, 30, impersonated_voting) # Second report - first NO and second NO has stuck/exited - (report_tx, extra_report_tx) = oracle_report( + (report_tx, extra_report_tx_list) = oracle_report( exclude_vaults_balances=True, extraDataFormat=1, extraDataHash=extra_data.data_hash, extraDataItemsCount=2, - extraDataList=extra_data.extra_data, + extraDataList=extra_data.extra_data_list, numExitedValidatorsByStakingModule=[nor_exited_count + 10], stakingModuleIdsWithNewlyExitedValidators=[staking_module.module_id], ) + distribute_reward_tx = distribute_reward(staking_module, stranger.address) # shares after report no1_summary = staking_module.getNodeOperatorSummary(no1_id) @@ -296,7 +298,7 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e no2_amount_penalty = no2_rewards_after_second_report // 2 penalty_shares = no1_amount_penalty + no2_amount_penalty - assert extra_report_tx.events["StETHBurnRequested"]["amountOfShares"] >= penalty_shares + assert distribute_reward_tx.events["StETHBurnRequested"]["amountOfShares"] >= penalty_shares # NO stats assert no1_summary["stuckValidatorsCount"] == 2 @@ -320,7 +322,7 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e # Events exited_signing_keys_count_events = parse_exited_signing_keys_count_changed_logs( - filter_transfer_logs(extra_report_tx.logs, web3.keccak(text="ExitedSigningKeysCountChanged(uint256,uint256)")) + filter_transfer_logs(extra_report_tx_list[0].logs, web3.keccak(text="ExitedSigningKeysCountChanged(uint256,uint256)")) ) assert exited_signing_keys_count_events[0]["nodeOperatorId"] == no1_id assert exited_signing_keys_count_events[0]["exitedValidatorsCount"][0] == 5 @@ -330,7 +332,7 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e stuck_penalty_state_changed_events = parse_stuck_penalty_state_changed_logs( filter_transfer_logs( - extra_report_tx.logs, web3.keccak(text="StuckPenaltyStateChanged(uint256,uint256,uint256,uint256)") + extra_report_tx_list[0].logs, web3.keccak(text="StuckPenaltyStateChanged(uint256,uint256,uint256,uint256)") ) ) assert stuck_penalty_state_changed_events[0]["nodeOperatorId"] == no1_id @@ -379,16 +381,17 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e # Third report - first NO: increase stuck to 0, desc exited to 7 = 5 + 2 # Second NO: same as prev report - (report_tx, extra_report_tx) = oracle_report( + (report_tx, extra_report_tx_list) = oracle_report( cl_diff=ETH(10), exclude_vaults_balances=True, extraDataFormat=1, extraDataHash=extra_data.data_hash, extraDataItemsCount=2, - extraDataList=extra_data.extra_data, + extraDataList=extra_data.extra_data_list, numExitedValidatorsByStakingModule=[nor_exited_count + 12], stakingModuleIdsWithNewlyExitedValidators=[staking_module.module_id], ) + distribute_reward_tx= distribute_reward(staking_module, stranger.address) no1_summary = staking_module.getNodeOperatorSummary(no1_id) no2_summary = staking_module.getNodeOperatorSummary(no2_id) @@ -432,8 +435,8 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e penalty_shares = no1_amount_penalty + no2_amount_penalty # diff by 2 share because of rounding # TODO: Fix below check when nor contains other penalized node operators - # assert almostEqWithDiff(extra_report_tx.events["StETHBurnRequested"]["amountOfShares"], penalty_shares, 2) - assert extra_report_tx.events["StETHBurnRequested"]["amountOfShares"] >= penalty_shares + # assert almostEqWithDiff(extra_report_tx_list[0].events["StETHBurnRequested"]["amountOfShares"], penalty_shares, 2) + assert distribute_reward_tx.events["StETHBurnRequested"]["amountOfShares"] >= penalty_shares # NO stats assert no3_summary["stuckPenaltyEndTimestamp"] == 0 @@ -455,14 +458,14 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e # events exited_signing_keys_count_events = parse_exited_signing_keys_count_changed_logs( - filter_transfer_logs(extra_report_tx.logs, web3.keccak(text="ExitedSigningKeysCountChanged(uint256,uint256)")) + filter_transfer_logs(extra_report_tx_list[0].logs, web3.keccak(text="ExitedSigningKeysCountChanged(uint256,uint256)")) ) assert exited_signing_keys_count_events[0]["nodeOperatorId"] == no1_id assert exited_signing_keys_count_events[0]["exitedValidatorsCount"][0] == 7 stuck_penalty_state_changed_events = parse_stuck_penalty_state_changed_logs( filter_transfer_logs( - extra_report_tx.logs, web3.keccak(text="StuckPenaltyStateChanged(uint256,uint256,uint256,uint256)") + extra_report_tx_list[0].logs, web3.keccak(text="StuckPenaltyStateChanged(uint256,uint256,uint256,uint256)") ) ) assert stuck_penalty_state_changed_events[0]["nodeOperatorId"] == no1_id @@ -501,15 +504,16 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e no3_balance_shares_before = shares_balance(no3_reward_address) # Fourth report - second NO: has stuck 2 keys - (report_tx, extra_report_tx) = oracle_report( + (report_tx, extra_report_tx_list) = oracle_report( exclude_vaults_balances=True, extraDataFormat=1, extraDataHash=extra_data.data_hash, extraDataItemsCount=2, - extraDataList=extra_data.extra_data, + extraDataList=extra_data.extra_data_list, numExitedValidatorsByStakingModule=[nor_exited_count + 12], stakingModuleIdsWithNewlyExitedValidators=[staking_module.module_id], ) + distribute_reward_tx = distribute_reward(staking_module, stranger.address) no1_summary = staking_module.getNodeOperatorSummary(no1_id) no2_summary = staking_module.getNodeOperatorSummary(no2_id) @@ -551,8 +555,8 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e no2_amount_penalty = no2_rewards_after_fourth_report // 2 # diff by 2 share because of rounding # TODO: Fix below check when nor contains other penalized node operators - # assert almostEqWithDiff(extra_report_tx.events["StETHBurnRequested"]["amountOfShares"], amount_penalty_second_no, 1) - assert extra_report_tx.events["StETHBurnRequested"]["amountOfShares"] >= no2_amount_penalty + # assert almostEqWithDiff(extra_report_tx_list[0].events["StETHBurnRequested"]["amountOfShares"], amount_penalty_second_no, 1) + assert distribute_reward_tx.events["StETHBurnRequested"]["amountOfShares"] >= no2_amount_penalty assert no3_summary["stuckPenaltyEndTimestamp"] == 0 @@ -606,7 +610,8 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e no3_balance_shares_before = shares_balance(no3_reward_address) # Fifth report - (report_tx, extra_report_tx) = oracle_report(exclude_vaults_balances=True) + (report_tx, extra_report_tx_list) = oracle_report(exclude_vaults_balances=True) + distribute_reward_tx = distribute_reward(staking_module, stranger.address) # shares after report no1_balance_shares_after = shares_balance(no1_reward_address) @@ -647,8 +652,8 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e no2_amount_penalty = no2_rewards_after_fifth_report // 2 # diff by 2 share because of rounding # TODO: Fix below check when nor contains other penalized node operators - # assert almostEqWithDiff(extra_report_tx.events["StETHBurnRequested"]["amountOfShares"], amount_penalty_second_no, 1) - assert extra_report_tx.events["StETHBurnRequested"]["amountOfShares"] >= no2_amount_penalty + # assert almostEqWithDiff(extra_report_tx_list[0].events["StETHBurnRequested"]["amountOfShares"], amount_penalty_second_no, 1) + assert distribute_reward_tx.events["StETHBurnRequested"]["amountOfShares"] >= no2_amount_penalty assert no3_summary["stuckPenaltyEndTimestamp"] == 0 @@ -687,7 +692,8 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e no3_balance_shares_before = shares_balance(no3_reward_address) # Seventh report - (report_tx, extra_report_tx) = oracle_report() + (report_tx, extra_report_tx_list) = oracle_report() + distribute_reward(staking_module, stranger.address) assert not staking_module.isOperatorPenalized(no1_id) assert not staking_module.isOperatorPenalized(no2_id) @@ -779,18 +785,19 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e assert first_no_summary_before["depositableValidatorsCount"] > 0 - target_limit_tx = staking_module.updateTargetValidatorsLimits(no1_id, True, 0, {"from": STAKING_ROUTER}) + target_limit_tx = staking_module.updateTargetValidatorsLimits(no1_id, 1, 0, {"from": STAKING_ROUTER}) target_validators_count_changed_events = parse_target_validators_count_changed( - filter_transfer_logs(target_limit_tx.logs, web3.keccak(text="TargetValidatorsCountChanged(uint256,uint256)")) + filter_transfer_logs(target_limit_tx.logs, web3.keccak(text="TargetValidatorsCountChanged(uint256,uint256,uint256)")) ) assert target_validators_count_changed_events[0]["nodeOperatorId"] == no1_id assert target_validators_count_changed_events[0]["targetValidatorsCount"][0] == 0 + # assert target_validators_count_changed_events[0]["targetLimitMode"] == 1 first_no_summary_after = staking_module.getNodeOperatorSummary(no1_id) assert first_no_summary_after["depositableValidatorsCount"] == 0 - assert first_no_summary_after["isTargetLimitActive"] + assert first_no_summary_after["targetLimitMode"] == 1 # Deposit ( @@ -808,16 +815,17 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e assert no3_deposited_keys_before != no3_deposited_keys_after # Disable target limit - target_limit_tx = staking_module.updateTargetValidatorsLimits(no1_id, False, 0, {"from": STAKING_ROUTER}) + target_limit_tx = staking_module.updateTargetValidatorsLimits(no1_id, 0, 0, {"from": STAKING_ROUTER}) target_validators_count_changed_events = parse_target_validators_count_changed( - filter_transfer_logs(target_limit_tx.logs, web3.keccak(text="TargetValidatorsCountChanged(uint256,uint256)")) + filter_transfer_logs(target_limit_tx.logs, web3.keccak(text="TargetValidatorsCountChanged(uint256,uint256,uint256)")) ) assert target_validators_count_changed_events[0]["nodeOperatorId"] == no1_id + # assert target_validators_count_changed_events[0]["targetLimitMode"][0] == 0 first_no_summary_after = staking_module.getNodeOperatorSummary(no1_id) assert first_no_summary_after["depositableValidatorsCount"] > 0 - assert not first_no_summary_after["isTargetLimitActive"] + assert first_no_summary_after["targetLimitMode"] == 0 # Deposit ( @@ -851,4 +859,4 @@ def test_sdvt(impersonated_voting, stranger, eth_whale): sdvt.testing_node_operator_ids = [0, 1, 2] fill_simple_dvt_ops_keys(stranger, 3, 100) - module_happy_path(sdvt, ExtraDataService(), impersonated_voting, eth_whale) + module_happy_path(sdvt, ExtraDataService(), impersonated_voting, eth_whale, stranger) From 3a1a15561f6de95dc56b78ce3ee40cadc6b3c893 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 2 Jul 2024 18:15:17 +0200 Subject: [PATCH 068/220] test: update enum name --- tests/regression/test_staking_router_stake_distribution.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/regression/test_staking_router_stake_distribution.py b/tests/regression/test_staking_router_stake_distribution.py index 42976759e..c18e04937 100644 --- a/tests/regression/test_staking_router_stake_distribution.py +++ b/tests/regression/test_staking_router_stake_distribution.py @@ -3,7 +3,7 @@ from utils.config import contracts from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.simple_dvt_helpers import fill_simple_dvt_ops_vetted_keys -from utils.test.staking_router_helpers import ModuleStatus +from utils.test.staking_router_helpers import StakingModuleStatus TOTAL_BASIS_POINTS = 10000 @@ -34,7 +34,7 @@ def get_modules_info(staking_router): (_, _, state, summary) = digest (id, _, module_fee, treasury_fee, target_share, status, _, _, _, _) = state (exited_keys, deposited_keys, depositable_keys) = summary - if status != ModuleStatus.ACTIVE.value: + if status != StakingModuleStatus.Active.value: # reset depositable keys in case of module is inactivated # https://github.com/lidofinance/lido-dao/blob/331ecec7fe3c8d57841fd73ccca7fb1cc9bc174e/contracts/0.8.9/StakingRouter.sol#L1230-L1232 depositable_keys = 0 From d3cff861c6a496e7815b8c9df541923d7e181f23 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 3 Jul 2024 09:53:36 +0200 Subject: [PATCH 069/220] test: use targetLimitMode instead of obsolete isTargetLimitActive --- .../test_accounting_oracle_extra_data_full_items.py | 2 +- tests/regression/test_easy_track.py | 4 ++-- tests/regression/test_easy_track_factories.py | 6 +++--- tests/regression/test_sdvt_rewards_happy_path.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 9b37c63a9..0b245942d 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -274,7 +274,7 @@ def fill_nor_with_old_and_new_operators( ) # Change staking limits for old node operators (change to new total added keys count) nor.setNodeOperatorStakingLimit(i, new_deposit_limit, {"from": evm_script_executor_eoa}) - nor.updateTargetValidatorsLimits(i, True, new_deposit_limit, {"from": contracts.staking_router}) + nor.updateTargetValidatorsLimits(i, 1, new_deposit_limit, {"from": contracts.staking_router}) return nor_count_before, added_nor_operators_count diff --git a/tests/regression/test_easy_track.py b/tests/regression/test_easy_track.py index 9a3b4772f..dd694d1de 100644 --- a/tests/regression/test_easy_track.py +++ b/tests/regression/test_easy_track.py @@ -222,7 +222,7 @@ def test_simple_dvt_set_operator_target_limit( no_summary = contracts.simple_dvt.getNodeOperatorSummary(no_id) - assert no_summary["isTargetLimitActive"] == False + assert no_summary["targetLimitMode"] == 0 assert no_summary["targetValidatorsCount"] == 0 calldata = _encode_calldata(["(uint256,bool,uint256)[]"], [[(no_id, True, target_limit)]]) @@ -231,7 +231,7 @@ def test_simple_dvt_set_operator_target_limit( no_summary = contracts.simple_dvt.getNodeOperatorSummary(no_id) - assert no_summary["isTargetLimitActive"] == True + assert no_summary["targetLimitMode"] == 1 assert no_summary["targetValidatorsCount"] == target_limit diff --git a/tests/regression/test_easy_track_factories.py b/tests/regression/test_easy_track_factories.py index ef7360fe3..72b476168 100644 --- a/tests/regression/test_easy_track_factories.py +++ b/tests/regression/test_easy_track_factories.py @@ -306,12 +306,12 @@ def test_update_target_validator_limits(stranger): ) summary_1 = contracts.simple_dvt.getNodeOperatorSummary(1) - assert summary_1["isTargetLimitActive"] == True + assert summary_1["targetLimitMode"] == 1 assert summary_1["targetValidatorsCount"] == 800 summary_2 = contracts.simple_dvt.getNodeOperatorSummary(2) - assert summary_2["isTargetLimitActive"] == False - assert summary_2["targetValidatorsCount"] == 0 # should be 0 because isTargetLimitActive is False + assert summary_2["targetLimitMode"] == 0 + assert summary_2["targetValidatorsCount"] == 0 # should be 0 because targetLimitMode is 0 def test_transfer_node_operator_manager(stranger): diff --git a/tests/regression/test_sdvt_rewards_happy_path.py b/tests/regression/test_sdvt_rewards_happy_path.py index 4f8f7f6f0..ad3f9b061 100644 --- a/tests/regression/test_sdvt_rewards_happy_path.py +++ b/tests/regression/test_sdvt_rewards_happy_path.py @@ -57,7 +57,7 @@ def test_sdvt_module_connected_to_router(): # full happy path test -def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participants, reward_wrapper, sdvt, stranger): +def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participants, reward_wrapper, stranger): """ Test happy path of rewards distribution Test adding new cluster to simple dvt module, depositing to simple dvt module, distributing and claiming rewards From d317741ad9f2383b2e0e68548e7b97f04934b438 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 3 Jul 2024 12:33:19 +0200 Subject: [PATCH 070/220] test: fix staking_router_stake_distribution tests --- .../test_staking_router_stake_distribution.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/regression/test_staking_router_stake_distribution.py b/tests/regression/test_staking_router_stake_distribution.py index c18e04937..9c669f7dd 100644 --- a/tests/regression/test_staking_router_stake_distribution.py +++ b/tests/regression/test_staking_router_stake_distribution.py @@ -10,10 +10,11 @@ class Module: def __init__( - self, id, target_share, module_fee, treasury_fee, deposited_keys, exited_keys, depositable_keys, status + self, id, stake_share_limit, module_fee, treasury_fee, deposited_keys, exited_keys, depositable_keys, status, + priorityExitShareThreshold, maxDepositsPerBlock, minDepositBlockDistance ): self.id = id - self.target_share = target_share + self.target_share = stake_share_limit self.status = status self.active_keys = 0 self.depositable_keys = depositable_keys @@ -23,7 +24,9 @@ def __init__( self.treasury_fee = treasury_fee self.deposited_keys = deposited_keys self.exited_keys = exited_keys - + self.priorityExitShareThreshold = priorityExitShareThreshold + self.maxDepositsPerBlock = maxDepositsPerBlock + self.minDepositBlockDistance = minDepositBlockDistance def get_modules_info(staking_router): # collect the modules information @@ -32,7 +35,7 @@ def get_modules_info(staking_router): for digest in module_digests: (_, _, state, summary) = digest - (id, _, module_fee, treasury_fee, target_share, status, _, _, _, _) = state + (id, _, module_fee, treasury_fee, stake_share_limit, status, _, _, _, _, priorityExitShareThreshold, maxDepositsPerBlock, minDepositBlockDistance) = state (exited_keys, deposited_keys, depositable_keys) = summary if status != StakingModuleStatus.Active.value: # reset depositable keys in case of module is inactivated @@ -40,7 +43,8 @@ def get_modules_info(staking_router): depositable_keys = 0 modules[id] = Module( - id, target_share, module_fee, treasury_fee, deposited_keys, exited_keys, depositable_keys, status + id, stake_share_limit, module_fee, treasury_fee, deposited_keys, exited_keys, depositable_keys, status, + priorityExitShareThreshold, maxDepositsPerBlock, minDepositBlockDistance ) # total_active_keys = sum([module.active_keys for module in modules.values()]) @@ -128,7 +132,7 @@ def test_stake_distribution(): for digest in module_digests_after_deposit: (_, _, state, summary) = digest - (id, _, _, _, _, _, _, _, _, _) = state + (id, _, _, _, _, _, _, _, _, _, _, _, _) = state (exited_keys, deposited_keys, _) = summary active_keys_after_deposit = deposited_keys - exited_keys @@ -183,8 +187,11 @@ def test_target_share_distribution(stranger): contracts.staking_router.updateStakingModule( sdvt_m_id, expected_target_share_1, + sdvt_m.priorityExitShareThreshold, sdvt_m.module_fee, sdvt_m.treasury_fee, + sdvt_m.maxDepositsPerBlock, + sdvt_m.minDepositBlockDistance, {"from": contracts.agent}, ) # add enough depositable keys to the target module to overcome the target share @@ -221,7 +228,7 @@ def test_target_share_distribution(stranger): for digest in module_digests_after_deposit: (_, _, state, summary) = digest - (id, _, _, _, _, _, _, _, _, _) = state + (id, _, _, _, _, _, _, _, _, _, _, _, _) = state (exited_keys, deposited_keys, _) = summary active_keys_after_deposit = deposited_keys - exited_keys From 4b5b89a33b204fb0ffb10deac1a6e55367a583a7 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 3 Jul 2024 16:13:23 +0200 Subject: [PATCH 071/220] test: use common helper for event parsing --- .../test_staking_module_happy_path.py | 42 +++++++------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/tests/regression/test_staking_module_happy_path.py b/tests/regression/test_staking_module_happy_path.py index d7fcb53f1..e297ed3a8 100644 --- a/tests/regression/test_staking_module_happy_path.py +++ b/tests/regression/test_staking_module_happy_path.py @@ -126,19 +126,7 @@ def parse_stuck_penalty_state_changed_logs(logs): return res -def parse_target_validators_count_changed(logs): - res = [] - for l in logs: - res.append( - { - "nodeOperatorId": eth_abi.decode(["uint256"], l["topics"][1])[0], - "targetValidatorsCount": eth_abi.decode(["uint256"], l["data"]), - } - ) - return res - - -def module_happy_path(staking_module, extra_data_service, impersonated_voting, eth_whale, stranger): +def module_happy_path(staking_module, extra_data_service, impersonated_voting, eth_whale, stranger, helpers): nor_exited_count, _, _ = contracts.staking_router.getStakingModuleSummary(staking_module.module_id) # all_modules = contracts.staking_router.getStakingModules() @@ -787,12 +775,11 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e target_limit_tx = staking_module.updateTargetValidatorsLimits(no1_id, 1, 0, {"from": STAKING_ROUTER}) - target_validators_count_changed_events = parse_target_validators_count_changed( - filter_transfer_logs(target_limit_tx.logs, web3.keccak(text="TargetValidatorsCountChanged(uint256,uint256,uint256)")) - ) - assert target_validators_count_changed_events[0]["nodeOperatorId"] == no1_id - assert target_validators_count_changed_events[0]["targetValidatorsCount"][0] == 0 - # assert target_validators_count_changed_events[0]["targetLimitMode"] == 1 + helpers.assert_single_event_named( + "TargetValidatorsCountChanged", + target_limit_tx, + {"nodeOperatorId": no1_id, "targetValidatorsCount": 0, "targetLimitMode": 1}, + ) first_no_summary_after = staking_module.getNodeOperatorSummary(no1_id) @@ -816,11 +803,12 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e # Disable target limit target_limit_tx = staking_module.updateTargetValidatorsLimits(no1_id, 0, 0, {"from": STAKING_ROUTER}) - target_validators_count_changed_events = parse_target_validators_count_changed( - filter_transfer_logs(target_limit_tx.logs, web3.keccak(text="TargetValidatorsCountChanged(uint256,uint256,uint256)")) + + helpers.assert_single_event_named( + "TargetValidatorsCountChanged", + target_limit_tx, + {"nodeOperatorId": no1_id, "targetValidatorsCount": 0, "targetLimitMode": 0}, ) - assert target_validators_count_changed_events[0]["nodeOperatorId"] == no1_id - # assert target_validators_count_changed_events[0]["targetLimitMode"][0] == 0 first_no_summary_after = staking_module.getNodeOperatorSummary(no1_id) @@ -846,17 +834,17 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e @pytest.mark.skip( "TODO: fix the test assumptions about the state of the chain (no exited validators, depositable ETH amount)" ) -def test_node_operator_registry(impersonated_voting, eth_whale): +def test_node_operator_registry(impersonated_voting, stranger, eth_whale, helpers): nor = contracts.node_operators_registry nor.module_id = 1 nor.testing_node_operator_ids = [35, 36, 37] - module_happy_path(nor, ExtraDataService(), impersonated_voting, eth_whale) + module_happy_path(nor, ExtraDataService(), impersonated_voting, eth_whale, stranger, helpers) -def test_sdvt(impersonated_voting, stranger, eth_whale): +def test_sdvt(impersonated_voting, stranger, eth_whale, helpers): sdvt = contracts.simple_dvt sdvt.module_id = 2 sdvt.testing_node_operator_ids = [0, 1, 2] fill_simple_dvt_ops_keys(stranger, 3, 100) - module_happy_path(sdvt, ExtraDataService(), impersonated_voting, eth_whale, stranger) + module_happy_path(sdvt, ExtraDataService(), impersonated_voting, eth_whale, stranger, helpers) From b0d13c0cb8c59902b93f911b17073672176bf770 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 4 Jul 2024 15:15:56 +0400 Subject: [PATCH 072/220] fix: add sdvt factory , remove old, add vote tests --- configs/config_holesky.py | 10 +- configs/config_mainnet.py | 4 +- scripts/mainnet/vote_sr_v2_mainnet.py | 169 +++++++++++++++----------- tests/test_vote_sr_v2_mainnet.py | 21 +++- 4 files changed, 124 insertions(+), 80 deletions(-) diff --git a/configs/config_holesky.py b/configs/config_holesky.py index e63d7e673..ab9826a96 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -24,7 +24,7 @@ LEGACY_ORACLE = "0x072f72BE3AcFE2c52715829F2CD9061A6C8fF019" NODE_OPERATORS_REGISTRY = "0x595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" # set address here after deploy -NODE_OPERATORS_REGISTRY_IMPL = "0x605A3AFadF35A8a8fa4f4Cd4fe34a09Bbcea7718" # set address here after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x41646708A7EDbe22BD635Cb838Ff9C0CfA99A3bE" # set address here after SR V2 deploy # Aragon APM Repos VOTING_REPO = "0x2997EA0D07D79038D83Cb04b3BB9A2Bc512E3fDA" @@ -92,7 +92,6 @@ EIP712_STETH = "0xE154732c5Eab277fd88a9fF6Bdff7805eD97BCB1" STAKING_ROUTER = "0xd6EbF043D30A7fe46D1Db32BA90a0A51207FE229" STAKING_ROUTER_IMPL = "0x9b5890E950E3Df487Bb64E0A6743cdE791139152" # set address here after SR V2 deploy - WITHDRAWAL_VAULT_IMPL = "0xd517d9d04DA9B47dA23df91261bd3bF435BE964A" # GateSeal @@ -108,13 +107,16 @@ SANDBOX_APP_ID = "0x85d2fceef13a6c14c43527594f79fb91a8ef8f15024a43486efac8df2b11e632" SIMPLE_DVT = "0x11a93807078f8BB880c1BD0ee4C387537de4b4b6" -SIMPLE_DVT_IMPL = "0x605A3AFadF35A8a8fa4f4Cd4fe34a09Bbcea7718" # same as for NOR +SIMPLE_DVT_IMPL = "0x41646708A7EDbe22BD635Cb838Ff9C0CfA99A3bE" # same as for NOR SIMPLE_DVT_REPO = "0x889dB59baf032E1dfD4fCA720e0833c24f1404C6" SANDBOX = "0xD6C2ce3BB8bea2832496Ac8b5144819719f343AC" -SANDBOX_IMPL = "0x605A3AFadF35A8a8fa4f4Cd4fe34a09Bbcea7718" +SANDBOX_IMPL = "0x41646708A7EDbe22BD635Cb838Ff9C0CfA99A3bE" SANDBOX_REPO = "0x00E75B5527a876B3F10C23436a0b896C626812d0" +SANDBOX_IMPL = "0x605A3AFadF35A8a8fa4f4Cd4fe34a09Bbcea7718" + + CSM = "0x4562c3e63c2e586cD1651B958C22F88135aCAd4f" CS_ACCOUNTING_ADDRESS = "0xc093e53e8F4b55A223c18A2Da6fA00e60DD5EFE1" CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xbF38618Ea09B503c1dED867156A0ea276Ca1AE37" diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 25b2bdebe..f980fe23d 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -255,8 +255,10 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" + STAKING_ROUTER_IMPL = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" # set address here after SR V2 deploy -STAKING_ROUTER_VERSION = 2 +STAKING_ROUTER_VERSION = 2 # do we need set this value now ? + # Not a precise but still some estimation of the fees. Assume here that both modules are filled # SR_MODULES_FEE = curated_module_fee * (100% - sdvt_module_share) + sdvt_module_fee * sdvt_module_share diff --git a/scripts/mainnet/vote_sr_v2_mainnet.py b/scripts/mainnet/vote_sr_v2_mainnet.py index d4b9c527a..21811ecd2 100644 --- a/scripts/mainnet/vote_sr_v2_mainnet.py +++ b/scripts/mainnet/vote_sr_v2_mainnet.py @@ -16,7 +16,9 @@ 14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, 15. Grant manage consensus role to agent ${AGENT}` 16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` -17. Revoke manage consensus role from agent ${AGENT}" +17. Revoke manage consensus role from agent ${AGENT} +18. Remove old target limit factory +19. Add Target limit for SDVT factory to ET CSM @@ -50,7 +52,8 @@ STAKING_ROUTER_IMPL, ACCOUNTING_ORACLE_IMPL, NODE_OPERATORS_REGISTRY_IMPL, - CS_ACCOUNTING_ADDRESS, + # CS_ACCOUNTING_ADDRESS, + EASYTRACK, ) from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description from utils.repo import ( @@ -58,7 +61,7 @@ add_implementation_to_sdvt_app_repo, ) from utils.permissions import encode_oz_grant_role, encode_oz_revoke_role -from utils.easy_track import add_evmscript_factory, create_permissions +from utils.easy_track import add_evmscript_factory, create_permissions, remove_evmscript_factory from utils.kernel import update_app_implementation from utils.voting import bake_vote_items, confirm_vote_script, create_vote @@ -86,8 +89,13 @@ CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 CS_ORACLE_INITIAL_EPOCH = 58050 +# !!!! that is locally deployed factory address, before run set you value +NEW_TARGET_LIMIT_FACTORY = "0xA3b48c7b901fede641B596A4C10a4630052449A6" +OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "" + description = """ -_REPLACE_ME_ +Proposal to support DSM 2.0 and CSM Module """ @@ -263,83 +271,96 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ] ), ), - # - # CSM - # ( - "18. Add staking module", - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.addStakingModule.encode_input( - CS_MODULE_NAME, - contracts.csm.address, - CS_STAKE_SHARE_LIMIT, - CS_PRIORITY_EXIT_SHARE_THRESHOLD, - CS_STAKING_MODULE_FEE, - CS_TREASURY_FEE, - CS_MAX_DEPOSITS_PER_BLOCK, - CS_MIN_DEPOSIT_BLOCK_DISTANCE, - ), - ), - ] - ), - ), - ( - "19. Grant request burn role to CSAccounting contract", - agent_forward( - [ - encode_oz_grant_role( - contract=contracts.burner, - role_name="REQUEST_BURN_SHARES_ROLE", - grant_to=CS_ACCOUNTING_ADDRESS, - ) - ] + "18. Remove old target limit factory", + remove_evmscript_factory( + factory=OLD_TARGET_LIMIT__FACTORY, ), ), ( - "20. Grant resume role to agent", - agent_forward( - [ - encode_oz_grant_role( - contract=contracts.csm, - role_name="RESUME_ROLE", - grant_to=contracts.agent, - ) - ] - ), - ), - ( - "21. Resume staking module", - agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), - ), - ( - "22. Revoke resume role from agent", - agent_forward( - [ - encode_oz_revoke_role( - contract=contracts.csm, - role_name="RESUME_ROLE", - revoke_from=contracts.agent, - ) - ] - ), - ), - ( - "23. Update initial epoch", - agent_forward( - [ - ( - contracts.csmHashConsensus.address, - contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), - ) - ] + "19. Add Target limit for SDVT factory to ET", + add_evmscript_factory( + factory=NEW_TARGET_LIMIT_FACTORY, + permissions=(create_permissions(contracts.simple_dvt, "updateTargetValidatorsLimits")), ), ), + # + # CSM + # + # ( + # "18. Add staking module", + # agent_forward( + # [ + # ( + # contracts.staking_router.address, + # contracts.staking_router.addStakingModule.encode_input( + # CS_MODULE_NAME, + # contracts.csm.address, + # CS_STAKE_SHARE_LIMIT, + # CS_PRIORITY_EXIT_SHARE_THRESHOLD, + # CS_STAKING_MODULE_FEE, + # CS_TREASURY_FEE, + # CS_MAX_DEPOSITS_PER_BLOCK, + # CS_MIN_DEPOSIT_BLOCK_DISTANCE, + # ), + # ), + # ] + # ), + # ), + # ( + # "19. Grant request burn role to CSAccounting contract", + # agent_forward( + # [ + # encode_oz_grant_role( + # contract=contracts.burner, + # role_name="REQUEST_BURN_SHARES_ROLE", + # grant_to=CS_ACCOUNTING_ADDRESS, + # ) + # ] + # ), + # ), + # ( + # "20. Grant resume role to agent", + # agent_forward( + # [ + # encode_oz_grant_role( + # contract=contracts.csm, + # role_name="RESUME_ROLE", + # grant_to=contracts.agent, + # ) + # ] + # ), + # ), + # ( + # "21. Resume staking module", + # agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), + # ), + # ( + # "22. Revoke resume role from agent", + # agent_forward( + # [ + # encode_oz_revoke_role( + # contract=contracts.csm, + # role_name="RESUME_ROLE", + # revoke_from=contracts.agent, + # ) + # ] + # ), + # ), + # ( + # "23. Update initial epoch", + # agent_forward( + # [ + # ( + # contracts.csmHashConsensus.address, + # contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), + # ) + # ] + # ), + # ), # ( # "24. Add CS settle EL stealing factory to ET", - # add_evmscript_factory( + # add_evmscript_factory( # factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, # permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), # ), @@ -364,7 +385,7 @@ def main(): if get_is_live(): tx_params["priority_fee"] = get_priority_fee() - vote_id, _ = start_vote(tx_params=tx_params, silent=False) + vote_id, _ = start_vote(tx_params=tx_params, silent=True) # disable temporary vote_id >= 0 and print(f"Vote created: {vote_id}.") diff --git a/tests/test_vote_sr_v2_mainnet.py b/tests/test_vote_sr_v2_mainnet.py index 3d49c1180..118883ebf 100644 --- a/tests/test_vote_sr_v2_mainnet.py +++ b/tests/test_vote_sr_v2_mainnet.py @@ -22,6 +22,12 @@ from utils.test.event_validators.repo_upgrade import validate_repo_upgrade_event, RepoUpgrade from utils.test.event_validators.aragon import validate_app_update_event from typing import NamedTuple +from utils.test.event_validators.easy_track import ( + validate_evmscript_factory_added_event, + validate_evmscript_factory_removed_event, + EVMScriptFactoryAdded, +) +from utils.easy_track import create_permissions class StakingModuleItem(NamedTuple): @@ -134,6 +140,9 @@ class StakingModuleItem(NamedTuple): } ] +OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" +NEW_TARGET_LIMIT_FACTORY = "0xA3b48c7b901fede641B596A4C10a4630052449A6" + def test_vote( helpers, @@ -206,7 +215,7 @@ def test_vote( # Events check events = group_voting_events(vote_tx) - assert len(events) == 17 + assert len(events) == 19 validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) @@ -262,6 +271,16 @@ def test_vote( events[16], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address ) + validate_evmscript_factory_removed_event(events[17], OLD_TARGET_LIMIT__FACTORY) + + validate_evmscript_factory_added_event( + events[18], + EVMScriptFactoryAdded( + factory_addr=NEW_TARGET_LIMIT_FACTORY, + permissions=(create_permissions(contracts.simple_dvt, "updateTargetValidatorsLimits")), + ), + ) + def check_ossifiable_proxy_impl(proxy, expected_impl): current_impl_address = proxy.proxy__getImplementation() From 0d411a48d6c98724ee86b298b4673a359c86aefd Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 4 Jul 2024 19:50:07 +0400 Subject: [PATCH 073/220] fix: csm part in voting on mainnet --- scripts/mainnet/vote_sr_v2_mainnet.py | 145 +++++++++++++------------- tests/test_vote_sr_v2_mainnet.py | 90 +++++++++++++++- 2 files changed, 159 insertions(+), 76 deletions(-) diff --git a/scripts/mainnet/vote_sr_v2_mainnet.py b/scripts/mainnet/vote_sr_v2_mainnet.py index 21811ecd2..1699d804e 100644 --- a/scripts/mainnet/vote_sr_v2_mainnet.py +++ b/scripts/mainnet/vote_sr_v2_mainnet.py @@ -52,7 +52,7 @@ STAKING_ROUTER_IMPL, ACCOUNTING_ORACLE_IMPL, NODE_OPERATORS_REGISTRY_IMPL, - # CS_ACCOUNTING_ADDRESS, + CS_ACCOUNTING_ADDRESS, EASYTRACK, ) from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description @@ -286,78 +286,77 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), # # CSM - # - # ( - # "18. Add staking module", - # agent_forward( - # [ - # ( - # contracts.staking_router.address, - # contracts.staking_router.addStakingModule.encode_input( - # CS_MODULE_NAME, - # contracts.csm.address, - # CS_STAKE_SHARE_LIMIT, - # CS_PRIORITY_EXIT_SHARE_THRESHOLD, - # CS_STAKING_MODULE_FEE, - # CS_TREASURY_FEE, - # CS_MAX_DEPOSITS_PER_BLOCK, - # CS_MIN_DEPOSIT_BLOCK_DISTANCE, - # ), - # ), - # ] - # ), - # ), - # ( - # "19. Grant request burn role to CSAccounting contract", - # agent_forward( - # [ - # encode_oz_grant_role( - # contract=contracts.burner, - # role_name="REQUEST_BURN_SHARES_ROLE", - # grant_to=CS_ACCOUNTING_ADDRESS, - # ) - # ] - # ), - # ), - # ( - # "20. Grant resume role to agent", - # agent_forward( - # [ - # encode_oz_grant_role( - # contract=contracts.csm, - # role_name="RESUME_ROLE", - # grant_to=contracts.agent, - # ) - # ] - # ), - # ), - # ( - # "21. Resume staking module", - # agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), - # ), - # ( - # "22. Revoke resume role from agent", - # agent_forward( - # [ - # encode_oz_revoke_role( - # contract=contracts.csm, - # role_name="RESUME_ROLE", - # revoke_from=contracts.agent, - # ) - # ] - # ), - # ), - # ( - # "23. Update initial epoch", - # agent_forward( - # [ - # ( - # contracts.csmHashConsensus.address, - # contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), - # ) - # ] - # ), - # ), + ( + "20. Add staking module", + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.addStakingModule.encode_input( + CS_MODULE_NAME, + contracts.csm.address, + CS_STAKE_SHARE_LIMIT, + CS_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_STAKING_MODULE_FEE, + CS_TREASURY_FEE, + CS_MAX_DEPOSITS_PER_BLOCK, + CS_MIN_DEPOSIT_BLOCK_DISTANCE, + ), + ), + ] + ), + ), + ( + "21. Grant request burn role to CSAccounting contract", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.burner, + role_name="REQUEST_BURN_SHARES_ROLE", + grant_to=CS_ACCOUNTING_ADDRESS, + ) + ] + ), + ), + ( + "22. Grant resume role to agent", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.csm, + role_name="RESUME_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "23. Resume staking module", + agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), + ), + ( + "24. Revoke resume role from agent", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.csm, + role_name="RESUME_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + ( + "25. Update initial epoch", + agent_forward( + [ + ( + contracts.csmHashConsensus.address, + contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), + ) + ] + ), + ), # ( # "24. Add CS settle EL stealing factory to ET", # add_evmscript_factory( diff --git a/tests/test_vote_sr_v2_mainnet.py b/tests/test_vote_sr_v2_mainnet.py index 118883ebf..6a4fab813 100644 --- a/tests/test_vote_sr_v2_mainnet.py +++ b/tests/test_vote_sr_v2_mainnet.py @@ -9,6 +9,7 @@ SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL, ACCOUNTING_ORACLE_IMPL, + CS_ACCOUNTING_ADDRESS, ) from scripts.mainnet.vote_sr_v2_mainnet import start_vote from utils.config import ( @@ -40,6 +41,11 @@ class StakingModuleItem(NamedTuple): min_deposit_block_distance: int +# CSM roles +RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" +REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" + +# SR roles STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" @@ -112,6 +118,26 @@ class StakingModuleItem(NamedTuple): } ) +CS_MODULE_NAME = "CommunityStaking" +CS_STAKE_SHARE_LIMIT = 2000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 +CS_STAKING_MODULE_FEE = 800 +CS_TREASURY_FEE = 200 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 58050 + +CSM_AFTER_VOTE = { + "id": 4, + "name": CS_MODULE_NAME, + "stakingModuleFee": CS_STAKING_MODULE_FEE, + "treasuryFee": CS_TREASURY_FEE, + "targetShare": CS_STAKE_SHARE_LIMIT, + "priorityExitShareThreshold": CS_PRIORITY_EXIT_SHARE_THRESHOLD, + "maxDepositsPerBlock": CS_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": CS_MIN_DEPOSIT_BLOCK_DISTANCE, +} + OLD_SR_ABI = bi = [ { "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], @@ -150,7 +176,6 @@ def test_vote( vote_ids_from_env, ): staking_router = contracts.staking_router - sr_proxy = interface.OssifiableProxy(contracts.staking_router) locator_proxy = interface.OssifiableProxy(contracts.lido_locator) nor_proxy = interface.AppProxyUpgradeable(contracts.node_operators_registry) @@ -184,6 +209,8 @@ def test_vote( # VEBO consensus version assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 + assert not contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) # START VOTE if len(vote_ids_from_env) > 0: @@ -196,6 +223,8 @@ def test_vote( print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") + assert staking_router.getStakingModulesCount() == 3 + # locator check_ossifiable_proxy_impl(locator_proxy, LIDO_LOCATOR_IMPL) # DSM @@ -212,10 +241,16 @@ def test_vote( # VEBO consensus version assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION + assert contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) + + assert contracts.csmHashConsensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + # Events check - events = group_voting_events(vote_tx) + # events = group_voting_events(vote_tx) + events = group_voting_events_from_receipt(vote_tx) - assert len(events) == 19 + assert len(events) == 25 validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) @@ -281,6 +316,18 @@ def test_vote( ), ) + # 20 - add of staking module + + # validate_module_add(events[19], CSM_AFTER_VOTE) + validate_grant_role_event(events[20], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, contracts.agent.address) + validate_grant_role_event(events[21], RESUME_ROLE, contracts.agent.address, contracts.agent.address) + + validate_resume_event(events[22]) + validate_revoke_role_event(events[23], RESUME_ROLE, contracts.agent.address, contracts.agent.address) + # validate_updateInitial_epoch(events[24]) + + # check_csm() + def check_ossifiable_proxy_impl(proxy, expected_impl): current_impl_address = proxy.proxy__getImplementation() @@ -481,3 +528,40 @@ def validate_vebo_consensus_version_set(event: EventDict): _events_chain = ["LogScriptCall", "LogScriptCall", "ConsensusVersionSet", "ScriptResult"] validate_events_chain([e.name for e in event], _events_chain) assert event["ConsensusVersionSet"]["version"] == VEBO_CONSENSUS_VERSION + + +def validate_resume_event(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "Resumed", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event.count("Resumed") == 1 + + +def validate_updateInitial_epoch(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "FrameConfigSet", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event["FrameConfigSet"]["newInitialEpoch"] == CS_ORACLE_INITIAL_EPOCH + + +def validate_module_add(event, csm): + _events_chain = [ + "LogScriptCall", + "StakingRouterETHDeposited", + "StakingModuleAdded", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ScriptResult", + ] + validate_events_chain([e.name for e in event], _events_chain) + + +def check_csm(): + cs = contracts.staking_router.getStakingModule(3) + + assert cs["name"] == CSM_AFTER_VOTE["name"] + assert cs["stakingModuleFee"] == CSM_AFTER_VOTE["stakingModuleFee"] + assert cs["treasuryFee"] == CSM_AFTER_VOTE["treasuryFee"] + assert cs["stakeShareLimit"] == CSM_AFTER_VOTE["targetShare"] + assert cs["priorityExitShareThreshold"] == CSM_AFTER_VOTE["priorityExitShareThreshold"] + assert cs["maxDepositsPerBlock"] == CSM_AFTER_VOTE["maxDepositsPerBlock"] + assert cs["minDepositBlockDistance"] == CSM_AFTER_VOTE["minDepositBlockDistance"] From 9d8a9b8a02b53eaa9f33b21fd93becb3d53a7c59 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 4 Jul 2024 21:09:00 +0400 Subject: [PATCH 074/220] fix: added all checks for csm except factory --- configs/config_mainnet copy.py | 312 ++++++++++++++ configs/config_mainnet.py | 19 +- scripts/holesky/vote_sr_v2_holesky.py | 398 ------------------ tests/test_vote_sr_v2_holesky.py | 577 -------------------------- tests/test_vote_sr_v2_mainnet.py | 60 ++- 5 files changed, 375 insertions(+), 991 deletions(-) create mode 100644 configs/config_mainnet copy.py delete mode 100644 scripts/holesky/vote_sr_v2_holesky.py delete mode 100644 tests/test_vote_sr_v2_holesky.py diff --git a/configs/config_mainnet copy.py b/configs/config_mainnet copy.py new file mode 100644 index 000000000..0eb5c93b3 --- /dev/null +++ b/configs/config_mainnet copy.py @@ -0,0 +1,312 @@ +# Ethereum Chain parameters +CHAIN_NETWORK_NAME = "mainnet" +CHAIN_SLOTS_PER_EPOCH = 32 +CHAIN_SECONDS_PER_SLOT = 12 +CHAIN_GENESIS_TIME = 1606824023 +CHAIN_DEPOSIT_CONTRACT = "0x00000000219ab540356cBB839Cbe05303d7705Fa" + +# DAO +ARAGON_KERNEL = "0xb8FFC3Cd6e7Cf5a098A1c92F48009765B24088Dc" +LDO_TOKEN = "0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32" +ARAGON_KERNEL_IMPL = "0x2b33CF282f867A7FF693A66e11B0FcC5552e4425" + +# Standard (or forked) Aragon apps +ACL = "0x9895F0F17cc1d1891b6f18ee0b483B6f221b37Bb" +AGENT = "0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c" +FINANCE = "0xB9E5CBB9CA5b0d659238807E84D0176930753d86" +VOTING = "0x2e59A20f205bB85a89C53f1936454680651E618e" +TOKEN_MANAGER = "0xf73a1260d222f447210581DDf212D915c09a3249" +ACL_IMPL = "0x9f3b9198911054B122fDb865f8A5Ac516201c339" +VOTING_IMPL = "0x72fb5253AD16307B9E773d2A78CaC58E309d5Ba4" + +# Our custom Aragon apps +LIDO = "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84" +LEGACY_ORACLE = "0x442af784A788A5bd6F42A01Ebe9F287a871243fb" +NODE_OPERATORS_REGISTRY = "0x55032650b14df07b85bF18A3a3eC8E0Af2e028d5" +SIMPLE_DVT = "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" + +LIDO_IMPL_V1 = "0x47EbaB13B806773ec2A2d16873e2dF770D130b50" +LEGACY_ORACLE_IMPL_V1 = "0x1430194905301504e8830ce4B0b0df7187E84AbD" +NODE_OPERATORS_REGISTRY_IMPL_V1 = "0x5d39ABaa161e622B99D45616afC8B837E9F19a25" # was used in archived tests + +# Aragon APM Repos +REPO_APP_ID = "0xbe49cbb8894efb45c933fd09dc87bdd94909553a9e1f511d7fc10f3dad1564f2" +APM_REGISTRY = "0x0cb113890b04B49455DfE06554e2D784598A29C9" +VOTING_REPO = "0x4Ee3118E3858E8D7164A634825BfE0F73d99C792" +LIDO_REPO = "0xF5Dc67E54FC96F993CD06073f71ca732C1E654B1" +NODE_OPERATORS_REGISTRY_REPO = "0x0D97E876ad14DB2b183CFeEB8aa1A5C788eB1831" +LEGACY_ORACLE_REPO = "0xF9339DE629973c60c4d2b76749c81E6F40960E3A" + +## LIDO_ARAGON_REPO_IMPL is common for Lido, NodeOperatorsRegistry, Oracle aragon apps +ARAGON_COMMON_REPO_IMPL = "0xa8A358E9bbB9fF60D4B89CBE5b2FE88f98b51B9D" + +# Other Aragon contracts +## For LIDO_EVM_SCRIPT_REGISTRY see Aragon Agent 0x853cc0D5917f49B57B8e9F89e491F5E18919093A +ARAGON_EVMSCRIPT_REGISTRY = "0x853cc0D5917f49B57B8e9F89e491F5E18919093A" +## See getEVMScriptExecutor(0x00000001) of any Aragon App or callsScript of LIDO_EASYTRACK_EVMSCRIPTEXECUTOR +ARAGON_CALLS_SCRIPT = "0x5cEb19e1890f677c3676d5ecDF7c501eBA01A054" + +# Other (non-aragon) protocol contracts +WSTETH_TOKEN = "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0" + +EXECUTION_LAYER_REWARDS_VAULT = "0x388C818CA8B9251b393131C08a736A67ccB19297" + +DEPOSIT_SECURITY_MODULE_V1 = "0x710B3303fB508a84F10793c1106e32bE873C24cd" +WITHDRAWAL_VAULT = "0xB9D7934878B5FB9610B3fE8A5e441e8fad7E293f" + +# EasyTracks +EASYTRACK = "0xF0211b7660680B49De1A7E9f25C65660F0a13Fea" + +EASYTRACK_EVMSCRIPT_EXECUTOR = "0xFE5986E06210aC1eCC1aDCafc0cc7f8D63B3F977" +EASYTRACK_INCREASE_NOP_STAKING_LIMIT_FACTORY = "0xFeBd8FAC16De88206d4b18764e826AF38546AfE0" +EASYTRACK_SIMPLE_DVT_TRUSTED_CALLER = "0x08637515E85A4633E23dfc7861e2A9f53af640f7" +EASYTRACK_SIMPLE_DVT_ADD_NODE_OPERATORS_FACTORY = "0xcAa3AF7460E83E665EEFeC73a7a542E5005C9639" +EASYTRACK_SIMPLE_DVT_ACTIVATE_NODE_OPERATORS_FACTORY = "0xCBb418F6f9BFd3525CE6aADe8F74ECFEfe2DB5C8" +EASYTRACK_SIMPLE_DVT_DEACTIVATE_NODE_OPERATORS_FACTORY = "0x8B82C1546D47330335a48406cc3a50Da732672E7" +EASYTRACK_SIMPLE_DVT_SET_VETTED_VALIDATORS_LIMITS_FACTORY = "0xD75778b855886Fc5e1eA7D6bFADA9EB68b35C19D" +EASYTRACK_SIMPLE_DVT_SET_NODE_OPERATOR_NAMES_FACTORY = "0x7d509BFF310d9460b1F613e4e40d342201a83Ae4" +EASYTRACK_SIMPLE_DVT_SET_NODE_OPERATOR_REWARD_ADDRESSES_FACTORY = "0x589e298964b9181D9938B84bB034C3BB9024E2C0" +EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" +EASYTRACK_SIMPLE_DVT_CHANGE_NODE_OPERATOR_MANAGERS_FACTORY = "0xE31A0599A6772BCf9b2bFc9e25cf941e793c9a7D" + +# Multisigs +FINANCE_MULTISIG = "0x48F300bD3C52c7dA6aAbDE4B683dEB27d38B9ABb" + +# Other +INSURANCE_FUND = "0x8B3f33234ABD88493c0Cd28De33D583B70beDe35" +RELAY_ALLOWED_LIST = "0xF95f069F9AD107938F6ba802a3da87892298610E" +CURVE_REWARDS_MANAGER = "0x753D5167C31fBEB5b49624314d74A957Eb271709" +BALANCER_REWARDS_MANAGER = "0x1dD909cDdF3dbe61aC08112dC0Fdf2Ab949f79D8" + +# Auxiliary addresses +LDO_HOLDER_ADDRESS_FOR_TESTS = "0x820fb25352bb0c5e03e07afc1d86252ffd2f0a18" +LDO_VOTE_EXECUTORS_FOR_TESTS = [ + "0x3e40d73eb977dc6a537af587d48316fee66e9c8c", + "0xb8d83908aab38a159f3da47a59d84db8e1838712", + "0xa2dfc431297aee387c05beef507e5335e684fbcd", +] +# General network addresses +DAI_TOKEN = "0x6b175474e89094c44da98b954eedeac495271d0f" +USDT_TOKEN = "0xdac17f958d2ee523a2206206994597c13d831ec7" +USDC_TOKEN = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" +WETH_TOKEN = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + +# +# Lido V2 upgrade entries +# Grouped the same as in docs +# + +# LidoLocator +LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" +LIDO_LOCATOR_IMPL = "0x26Df0Ea798971A97Ae121514B32999DfDb220e1f" # set address here after SR V2 deploy + +# Other upgrade addresses +LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" +DUMMY_IMPL = "0x6F6541C2203196fEeDd14CD2C09550dA1CbEDa31" +INITIAL_DEAD_TOKEN_HOLDER = "0x000000000000000000000000000000000000dead" +DEPLOYER_EOA_LOCATOR = "0x2A78076BF797dAC2D25c9568F79b61aFE565B88C" +DEPLOYER_EOA = "0x8Ea83AD72396f1E0cD2f8E72b1461db8Eb6aF7B5" + +# 0x01...withdrawal_vault or Lido.getWithdrawalCredentials() +WITHDRAWAL_CREDENTIALS = "0x010000000000000000000000b9d7934878b5fb9610b3fe8a5e441e8fad7e293f" + +# Lido +LIDO_IMPL = "0x17144556fd3424EDC8Fc8A4C940B2D04936d17eb" +# see Lido's proxy appId() +LIDO_ARAGON_APP_ID = "0x3ca7c3e38968823ccb4c78ea688df41356f182ae1d159e4ee608d30d68cef320" +LIDO_MAX_STAKE_LIMIT_ETH = 150_000 + +# LegacyOracle (former LidoOracle) +## address is LIDO_LEGACY_ORACLE +LEGACY_ORACLE_IMPL = "0xa29b819654cE6224A222bb5f586920105E2D7E0E" +## see LidoOracle's proxy appId() +ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" + +# NodeOperatorsRegistry aka Curated Staking Module +NODE_OPERATORS_REGISTRY_IMPL = "0xa9efDEf197130B945462163a0B852019BA529a66" # set address here after SR V2 deploy +## see NodeOperatorsRegistry's proxy appId() +NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" +NODE_OPERATORS_REGISTRY_VERSION = 3 + +CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY = 432000 +CURATED_STAKING_MODULE_TARGET_SHARE_BP = 10000 +CURATED_STAKING_MODULE_MODULE_FEE_BP = 500 +CURATED_STAKING_MODULE_TREASURY_FEE_BP = 500 +CURATED_STAKING_MODULE_ID = 1 +CURATED_STAKING_MODULE_NAME = "curated-onchain-v1" +CURATED_STAKING_MODULE_TYPE = ( + # bytes32("curated-onchain-v1") + "0x637572617465642d6f6e636861696e2d76310000000000000000000000000000" +) +CURATED_STAKING_MODULE_OPERATORS_COUNT = 39 +CURATED_STAKING_MODULE_OPERATORS_ACTIVE_COUNT = 37 + +# NodeOperatorsRegistry clone aka SimpleDVT +SIMPLE_DVT_IMPL = "0xa9efDEf197130B945462163a0B852019BA529a66" +SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" +## see SimpleDVT's proxy appId() +SIMPLE_DVT_ARAGON_APP_NAME = "simple-dvt" +SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" +SIMPLE_DVT_MODULE_STUCK_PENALTY_DELAY = 432000 +SIMPLE_DVT_MODULE_TARGET_SHARE_BP = 50 +SIMPLE_DVT_MODULE_MODULE_FEE_BP = 800 +SIMPLE_DVT_MODULE_TREASURY_FEE_BP = 200 +SIMPLE_DVT_MODULE_ID = 2 +SIMPLE_DVT_MODULE_NAME = "SimpleDVT" +SIMPLE_DVT_MODULE_TYPE = ( + # bytes32("curated-onchain-v1") + "0x637572617465642d6f6e636861696e2d76310000000000000000000000000000" +) +SIMPLE_DVT_VERSION = 3 + +# OracleDaemonConfig +ORACLE_DAEMON_CONFIG = "0xbf05A929c3D7885a6aeAd833a992dA6E5ac23b09" +NORMALIZED_CL_REWARD_PER_EPOCH = 64 +NORMALIZED_CL_REWARD_MISTAKE_RATE_BP = 1000 # 10% +REBASE_CHECK_NEAREST_EPOCH_DISTANCE = 1 +REBASE_CHECK_DISTANT_EPOCH_DISTANCE = 23 # 10% of AO 225 epochs frame +VALIDATOR_DELAYED_TIMEOUT_IN_SLOTS = 7200 # 1 day +VALIDATOR_DELINQUENT_TIMEOUT_IN_SLOTS = 28800 # 4 days +NODE_OPERATOR_NETWORK_PENETRATION_THRESHOLD_BP = 100 # 1% +PREDICTION_DURATION_IN_SLOTS = 50400 +FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT = 1350 # 6 days + +# OracleReportSanityChecker +ORACLE_REPORT_SANITY_CHECKER = "0x9305c1Dbfe22c12c66339184C0025d7006f0f1cC" +APPEARED_VALIDATORS_PER_DAY_LIMIT = 43200 +EXITED_VALIDATORS_PER_DAY_LIMIT = 9000 +ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT = 500 # 5% +ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% +SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT = 50 # 0.5% +MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT = 600 +MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT = 8 +MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT = 62 +REQUEST_TIMESTAMP_MARGIN = 7680 # 2 hours rounded to epoch length +MAX_POSITIVE_TOKEN_REBASE = 750000 + +# Burner +BURNER = "0xD15a672319Cf0352560eE76d9e89eAB0889046D3" +TOTAL_NON_COVER_SHARES_BURNT = 32145684728326685744 +TOTAL_COVER_SHARES_BURNT = 0 + +# DepositSecurityModule +DEPOSIT_SECURITY_MODULE = "0x06786bCbc114bbfa670E30A1AC35dFd1310Be82f" # set address here after SR V2 deploy +DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact +DSM_MAX_OPERATORS_PER_UNVETTING = 200 +DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS = 6646 +## Migrated from LIDO_DEPOSIT_SECURITY_MODULE_V1 +DSM_GUARDIANS = [ + "0x5fd0dDbC3351d009eb3f88DE7Cd081a614C519F1", + "0x7912Fa976BcDe9c2cf728e213e892AD7588E6AaF", + "0x14D5d5B71E048d2D75a39FfC5B407e3a3AB6F314", + "0xf82D88217C249297C6037BA77CE34b3d8a90ab43", + "0xa56b128Ea2Ea237052b0fA2a96a387C0E43157d8", + "0xd4EF84b638B334699bcf5AF4B0410B8CCD71943f", +] +DSM_GUARDIAN_QUORUM = 4 + +# AccountingOracle +# and its corresponding HashConsensus +ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" +ACCOUNTING_ORACLE_IMPL = "0xD61210E756f7D71Cc4F74abF0747D65Ea9d7525b" # set address here after SR V2 deploy +HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" +AO_EPOCHS_PER_FRAME = 225 +AO_FAST_LANE_LENGTH_SLOTS = 100 +AO_CONSENSUS_VERSION = 2 + +# ValidatorsExitBusOracle +VALIDATORS_EXIT_BUS_ORACLE = "0x0De4Ea0184c2ad0BacA7183356Aea5B8d5Bf5c6e" +VALIDATORS_EXIT_BUS_ORACLE_IMPL = "0xA89Ea51FddE660f67d1850e03C9c9862d33Bc42c" +HASH_CONSENSUS_FOR_VEBO = "0x7FaDB6358950c5fAA66Cb5EB8eE5147De3df355a" +VEBO_EPOCHS_PER_FRAME = 75 +VEBO_FAST_LANE_LENGTH_SLOTS = 100 +VEBO_CONSENSUS_VERSION = 2 + + +# AccountingOracle and ValidatorsExitBusOracle +## Migrated from LidoOracle (LegacyOracle) +ORACLE_QUORUM = 5 +ORACLE_COMMITTEE = ( + "0x140Bd8FbDc884f48dA7cb1c09bE8A2fAdfea776E", + # "0x1d0813bf088BE3047d827D98524fBf779Bc25F00", Excluded from members in vote 2024/01/16 + "0xA7410857ABbf75043d61ea54e07D57A6EB6EF186", + "0x404335BcE530400a5814375E7Ec1FB55fAff3eA2", + "0x946D3b081ed19173dC83Cd974fC69e1e760B7d78", + "0x007DE4a5F7bc37E2F26c0cb2E8A95006EE9B89b5", + "0xEC4BfbAF681eb505B94E4a7849877DC6c600Ca3A", + "0x61c91ECd902EB56e314bB2D5c5C07785444Ea1c8", + "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d", + "0xc79F702202E3A6B0B6310B537E786B9ACAA19BAf", # Added into members in vote 2024/01/16 +) + +# WithdrawalQueueERC721 +WITHDRAWAL_QUEUE = "0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1" +WITHDRAWAL_QUEUE_IMPL = "0xE42C659Dc09109566720EA8b2De186c2Be7D94D9" +WQ_ERC721_TOKEN_NAME = "Lido: stETH Withdrawal NFT" +WQ_ERC721_TOKEN_SYMBOL = "unstETH" +WQ_ERC721_TOKEN_BASE_URI = "https://wq-api.lido.fi/v1/nft" + +# WithdrawalsVault +WITHDRAWAL_VAULT_IMPL_V1 = "0xe681faB8851484B57F32143FD78548f25fD59980" +WITHDRAWAL_VAULT_IMPL = "0xCC52f17756C04bBa7E377716d7062fC36D7f69Fd" + +# EIP712StETH +EIP712_STETH = "0x8F73e4C2A6D852bb4ab2A45E6a9CF5715b3228B7" + +# StakingRouter +STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" + +STAKING_ROUTER_IMPL = "0x49AeF2C4005Bf572665b09014A563B5b9E46Df21" # set address here after SR V2 deploy +STAKING_ROUTER_VERSION = 2 + + +# Not a precise but still some estimation of the fees. Assume here that both modules are filled +# SR_MODULES_FEE = curated_module_fee * (100% - sdvt_module_share) + sdvt_module_fee * sdvt_module_share + +SR_MODULES_FEE_BP = ( + CURATED_STAKING_MODULE_MODULE_FEE_BP * (100_00 - SIMPLE_DVT_MODULE_TARGET_SHARE_BP) + + SIMPLE_DVT_MODULE_MODULE_FEE_BP * SIMPLE_DVT_MODULE_TARGET_SHARE_BP +) // 100_00 + +SR_TREASURY_FEE_BP = ( + CURATED_STAKING_MODULE_TREASURY_FEE_BP * (100_00 - SIMPLE_DVT_MODULE_TARGET_SHARE_BP) + + SIMPLE_DVT_MODULE_TREASURY_FEE_BP * SIMPLE_DVT_MODULE_TARGET_SHARE_BP +) // 100_00 + +SR_MODULES_FEE_E20 = ( + CURATED_STAKING_MODULE_MODULE_FEE_BP * (100_00 - SIMPLE_DVT_MODULE_TARGET_SHARE_BP) + + SIMPLE_DVT_MODULE_MODULE_FEE_BP * SIMPLE_DVT_MODULE_TARGET_SHARE_BP +) * 10**12 + +# same as for SR_MODULES_FEE_E20 +SR_TREASURY_FEE_E20 = ( + CURATED_STAKING_MODULE_TREASURY_FEE_BP * (100_00 - SIMPLE_DVT_MODULE_TARGET_SHARE_BP) + + SIMPLE_DVT_MODULE_TREASURY_FEE_BP * SIMPLE_DVT_MODULE_TARGET_SHARE_BP +) * 10**12 + +SR_BASE_PRECISION_E20 = 100 * 10**18 + +# GateSeal +GATE_SEAL_FACTORY = "0x6C82877cAC5a7A739f16Ca0A89c0A328B8764A24" +GATE_SEAL = "0x79243345eDbe01A7E42EDfF5900156700d22611c" +GATE_SEAL_PAUSE_DURATION = 518400 # 6 days +GATE_SEAL_EXPIRY_TIMESTAMP = 1743465600 # 2025-05-01 00:00GMT +GATE_SEAL_COMMITTEE = "0x8772E3a2D86B9347A2688f9bc1808A6d8917760C" + +# Aragon Permissions test +ACL_DEPLOY_BLOCK_NUMBER = 11473216 + +# Obsolete (can be removed after V2 upgrade) +SELF_OWNED_STETH_BURNER = "0xB280E33812c0B09353180e92e27b8AD399B07f26" + +# Anchor +ANCHOR_VAULT_PROXY = "0xA2F987A546D4CD1c607Ee8141276876C26b72Bdf" + +# 0xSplits +SPLIT_MAIN = "0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE" + +# Rewards Wrapper (aka ObolLidoSplit) +OBOL_LIDO_SPLIT_FACTORY = "0xA9d94139A310150Ca1163b5E23f3E1dbb7D9E2A6" +OBOL_LIDO_SPLIT_IMPL = "0x2fB59065F049e0D0E3180C6312FA0FeB5Bbf0FE3" + +SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index f980fe23d..c28d57858 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -98,7 +98,7 @@ # LidoLocator LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0x26Df0Ea798971A97Ae121514B32999DfDb220e1f" # set address here after SR V2 deploy # Other upgrade addresses LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" @@ -123,7 +123,7 @@ ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" # NodeOperatorsRegistry aka Curated Staking Module -NODE_OPERATORS_REGISTRY_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" # set address here after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0xa9efDEf197130B945462163a0B852019BA529a66" # set address here after SR V2 deploy ## see NodeOperatorsRegistry's proxy appId() NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" NODE_OPERATORS_REGISTRY_VERSION = 3 @@ -142,7 +142,7 @@ CURATED_STAKING_MODULE_OPERATORS_ACTIVE_COUNT = 37 # NodeOperatorsRegistry clone aka SimpleDVT -SIMPLE_DVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" +SIMPLE_DVT_IMPL = "0xa9efDEf197130B945462163a0B852019BA529a66" SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" ## see SimpleDVT's proxy appId() SIMPLE_DVT_ARAGON_APP_NAME = "simple-dvt" @@ -190,7 +190,7 @@ TOTAL_COVER_SHARES_BURNT = 0 # DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # set address here after SR V2 deploy +DEPOSIT_SECURITY_MODULE = "0x06786bCbc114bbfa670E30A1AC35dFd1310Be82f" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact DSM_MAX_OPERATORS_PER_UNVETTING = 200 DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS = 6646 @@ -208,7 +208,7 @@ # AccountingOracle # and its corresponding HashConsensus ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0xD61210E756f7D71Cc4F74abF0747D65Ea9d7525b" # set address here after SR V2 deploy HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 @@ -256,8 +256,8 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" -STAKING_ROUTER_IMPL = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" # set address here after SR V2 deploy -STAKING_ROUTER_VERSION = 2 # do we need set this value now ? +STAKING_ROUTER_IMPL = "0x49AeF2C4005Bf572665b09014A563B5b9E46Df21" # set address here after SR V2 deploy +STAKING_ROUTER_VERSION = 2 # Not a precise but still some estimation of the fees. Assume here that both modules are filled @@ -310,3 +310,8 @@ OBOL_LIDO_SPLIT_IMPL = "0x2fB59065F049e0D0E3180C6312FA0FeB5Bbf0FE3" SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" + + +CSM = "0xAAF0F531b7947e8492f21862471d61d5305f7538" +CS_ACCOUNTING_ADDRESS = "0x81f4f47aa3bBd154171C877b4d70F6C9EeCAb216" +CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xe4a4B3Bc2787aA913e5b4bbce907e8b213250BDe" diff --git a/scripts/holesky/vote_sr_v2_holesky.py b/scripts/holesky/vote_sr_v2_holesky.py deleted file mode 100644 index ee64c8aeb..000000000 --- a/scripts/holesky/vote_sr_v2_holesky.py +++ /dev/null @@ -1,398 +0,0 @@ -""" -SR V2 -1. Update locator implementation -2. Revoke pause role from old DSM -3. Revoke resume role from old DSM -4. Grant unvetting role to new DSM -5. Update SR implementation -6. Call finalize upgrade on SR -7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo -8. Update `NodeOperatorsRegistry` implementation -9. Finalize NOR upgrade -10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo -11. Update `SimpleDVT` implementation -12. Finalize SimpleDVT upgrade -13. Publish new `Sandbox` implementation in Sandbox app APM repo -14. Update `Sandbox` implementation -15. Finalize Sandbox upgrade -16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, -17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, -18. Grant manage consensus role to agent ${AGENT}` -19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` -20. Revoke manage consensus role from agent ${AGENT}" - -CSM - -21. Add staking module -22. Grant request burn role to CSAccounting contract -23. Grant resume role to agent -24. Resume staking module -25. Revoke resume role from agent -26. Update initial epoch -27. Add CS settle EL stealing factory to ET -""" - -import time - -try: - from brownie import interface, accounts -except ImportError: - print("You're probably running inside Brownie console. Please call:") - print("set_console_globals(interface=interface)") - - -from typing import Dict, Tuple, Optional -from utils.config import ( - get_deployer_account, - get_is_live, - get_priority_fee, - contracts, - NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, - SIMPLE_DVT_ARAGON_APP_ID, - SANDBOX_APP_ID, - LIDO_LOCATOR_IMPL, - STAKING_ROUTER_IMPL, - ACCOUNTING_ORACLE_IMPL, - NODE_OPERATORS_REGISTRY_IMPL, - CS_ACCOUNTING_ADDRESS, -) -from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description -from utils.repo import ( - add_implementation_to_nor_app_repo, - add_implementation_to_sdvt_app_repo, - add_implementation_to_sandbox_app_repo, -) -from utils.permissions import encode_oz_grant_role, encode_oz_revoke_role -from utils.easy_track import add_evmscript_factory, create_permissions -from utils.kernel import update_app_implementation -from utils.voting import bake_vote_items, confirm_vote_script, create_vote - -from brownie.network.transaction import TransactionReceipt -from utils.agent import agent_forward - - -# SR -PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] -MAX_DEPOSITS_PER_BLOCK = [150, 50, 50] -MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] -NOR_VERSION = ["2", "0", "0"] -SDVT_VERSION = ["2", "0", "0"] -SANDBOX_VERSION = ["2", "0", "0"] -AO_CONSENSUS_VERSION = 2 -VEBO_CONSENSUS_VERSION = 2 - -# CSM -CS_MODULE_NAME = "Community Staking" -CS_STAKE_SHARE_LIMIT = 1000 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2000 -CS_STAKING_MODULE_FEE = 700 -CS_TREASURY_FEE = 300 -CS_MAX_DEPOSITS_PER_BLOCK = 30 -CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 63055 - -EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0x07696EA8A5b53C3E35d9cce10cc62c6c79C4691D" - - -description = """ -Proposal to support DSM 2.0 and CSM Module -""" - - -def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.lido_locator) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_staking_router_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.staking_router) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_staking_router_finalize() -> Tuple[str, str]: - proxy = interface.StakingRouter(contracts.staking_router) - return proxy.address, proxy.finalizeUpgrade_v2.encode_input( - PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES - ) - - -def encode_nor_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.node_operators_registry) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_sdvt_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.simple_dvt) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_sandbox_finalize() -> Tuple[str, str]: - proxy = interface.NodeOperatorsRegistry(contracts.sandbox) - return proxy.address, proxy.finalizeUpgrade_v3.encode_input() - - -def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: - proxy = interface.OssifiableProxy(contracts.accounting_oracle) - return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) - - -def encode_ao_finalize() -> Tuple[str, str]: - proxy = interface.AccountingOracle(contracts.accounting_oracle) - return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) - - -def encode_set_consensus_version() -> Tuple[str, str]: - proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) - return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) - - -def get_repo_uri(repo_address: str) -> str: - contract = interface.Repo(repo_address).getLatest() - return contract["contentURI"] - - -def get_repo_version(repo_address: str) -> tuple[int, int, int]: - contract = interface.Repo(repo_address).getLatest() - return contract["semanticVersion"] - - -def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: - """Prepare and run voting.""" - nor_repo = contracts.nor_app_repo.address - simple_dvt_repo = contracts.simple_dvt_app_repo.address - sandbox_repo = contracts.sandbox_repo.address - - nor_uri = get_repo_uri(nor_repo) - simple_dvt_uri = get_repo_uri(simple_dvt_repo) - sandbox_uri = get_repo_uri(sandbox_repo) - - vote_desc_items, call_script_items = zip( - # - # SR 2 - # - ( - "1. Update locator implementation", - agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), - ), - ( - "2. Revoke pause role from old DSM", - agent_forward( - [ - encode_oz_revoke_role( - contract=contracts.staking_router, - role_name="STAKING_MODULE_PAUSE_ROLE", - revoke_from=contracts.deposit_security_module_v2, - ) - ] - ), - ), - ( - "3. Revoke resume role from old DSM", - agent_forward( - [ - encode_oz_revoke_role( - contract=contracts.staking_router, - role_name="STAKING_MODULE_RESUME_ROLE", - revoke_from=contracts.deposit_security_module_v2, - ) - ] - ), - ), - ( - "4. Grant unvetting role to new DSM", - agent_forward( - [ - encode_oz_grant_role( - contract=contracts.staking_router, - role_name="STAKING_MODULE_UNVETTING_ROLE", - grant_to=contracts.deposit_security_module, - ) - ] - ), - ), - ( - "5. Update SR implementation", - agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), - ), - ( - "6. Call finalize upgrade on SR", - encode_staking_router_finalize(), - ), - ( - "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", - add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), - ), - ( - "8. Update `NodeOperatorsRegistry` implementation", - update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - ), - ( - "9. Finalize NOR upgrade", - encode_nor_finalize(), - ), - ( - "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", - add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), - ), - ( - "11. Update `SimpleDVT` implementation", - update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - ), - ( - "12. Finalize SimpleDVT upgrade", - encode_sdvt_finalize(), - ), - ( - "13. Publish new `Sandbox` implementation in Sandbox app APM repo", - add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), - ), - ( - "14. Update `Sandbox` implementation", - update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), - ), - ( - "15. Finalize Sandbox upgrade", - encode_sandbox_finalize(), - ), - ( - "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", - agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), - ), - ( - "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", - encode_ao_finalize(), - ), - ( - "18. Grant manage consensus role to agent ${AGENT}", - agent_forward( - [ - encode_oz_grant_role( - contract=contracts.validators_exit_bus_oracle, - role_name="MANAGE_CONSENSUS_VERSION_ROLE", - grant_to=contracts.agent, - ) - ] - ), - ), - ( - "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", - agent_forward([encode_set_consensus_version()]), - ), - ( - "20. Revoke manage consensus role from agent ${AGENT}", - agent_forward( - [ - encode_oz_revoke_role( - contract=contracts.validators_exit_bus_oracle, - role_name="MANAGE_CONSENSUS_VERSION_ROLE", - revoke_from=contracts.agent, - ) - ] - ), - ), - # - # CSM - # - ( - "21. Add staking module", - agent_forward( - [ - ( - contracts.staking_router.address, - contracts.staking_router.addStakingModule.encode_input( - CS_MODULE_NAME, - contracts.csm.address, - CS_STAKE_SHARE_LIMIT, - CS_PRIORITY_EXIT_SHARE_THRESHOLD, - CS_STAKING_MODULE_FEE, - CS_TREASURY_FEE, - CS_MAX_DEPOSITS_PER_BLOCK, - CS_MIN_DEPOSIT_BLOCK_DISTANCE, - ), - ), - ] - ), - ), - ( - "22. Grant request burn role to CSAccounting contract", - agent_forward( - [ - encode_oz_grant_role( - contract=contracts.burner, - role_name="REQUEST_BURN_SHARES_ROLE", - grant_to=CS_ACCOUNTING_ADDRESS, - ) - ] - ), - ), - ( - "23. Grant resume role to agent", - agent_forward( - [ - encode_oz_grant_role( - contract=contracts.csm, - role_name="RESUME_ROLE", - grant_to=contracts.agent, - ) - ] - ), - ), - ( - "24. Resume staking module", - agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), - ), - ( - "25. Revoke resume role from agent", - agent_forward( - [ - encode_oz_revoke_role( - contract=contracts.csm, - role_name="RESUME_ROLE", - revoke_from=contracts.agent, - ) - ] - ), - ), - ( - "26. Update initial epoch", - agent_forward( - [ - ( - contracts.csmHashConsensus.address, - contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), - ) - ] - ), - ), - ( - "27. Add CS settle EL stealing factory to ET", - add_evmscript_factory( - factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, - permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), - ), - ), - ) - - vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) - - if silent: - desc_ipfs = calculate_vote_ipfs_description(description) - else: - desc_ipfs = upload_vote_ipfs_description(description) - - return confirm_vote_script(vote_items, silent, desc_ipfs) and list( - create_vote(vote_items, tx_params, desc_ipfs=desc_ipfs) - ) - - -def main(): - tx_params = {"from": get_deployer_account()} - - if get_is_live(): - tx_params["priority_fee"] = get_priority_fee() - - vote_id, _ = start_vote(tx_params=tx_params, silent=True) # disable IPFS description for Holesky - - vote_id >= 0 and print(f"Vote created: {vote_id}.") - - time.sleep(10) # hack for waiting thread #2. diff --git a/tests/test_vote_sr_v2_holesky.py b/tests/test_vote_sr_v2_holesky.py deleted file mode 100644 index 7448f8da4..000000000 --- a/tests/test_vote_sr_v2_holesky.py +++ /dev/null @@ -1,577 +0,0 @@ -import pytest - -from utils.config import ( - contracts, - get_priority_fee, - STAKING_ROUTER_IMPL, - LIDO_LOCATOR_IMPL, - NODE_OPERATORS_REGISTRY_IMPL, - NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, - SIMPLE_DVT_ARAGON_APP_ID, - SIMPLE_DVT_IMPL, - ACCOUNTING_ORACLE_IMPL, - SANDBOX_IMPL, - CS_ACCOUNTING_ADDRESS, -) -from scripts.holesky.vote_sr_v2_holesky import start_vote -from utils.config import ( - contracts, - LDO_HOLDER_ADDRESS_FOR_TESTS, -) -from brownie import interface, Contract -from utils.test.tx_tracing_helpers import * -from utils.test.event_validators.permission import validate_grant_role_event, validate_revoke_role_event -from utils.test.event_validators.common import validate_events_chain -from utils.test.event_validators.repo_upgrade import validate_repo_upgrade_event, RepoUpgrade -from utils.test.event_validators.aragon import validate_app_update_event -from typing import NamedTuple - - -class StakingModuleItem(NamedTuple): - id: int - staking_module_fee: int - stake_share_limit: int - treasury_fee: int - priority_exit_share_threshold: int - max_deposits_per_block: int - min_deposit_block_distance: int - - -STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" -PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" -STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" -MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" -STAKING_MODULE_MANAGE_ROLE = "0x3105bcbf19d4417b73ae0e58d508a65ecf75665e46c2622d8521732de6080c48" -REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" -RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" -OLD_LOCATOR_IMPL_ADDRESS = "0xDba5Ad530425bb1b14EECD76F1b4a517780de537" -OLD_SR_IMPL_ADDRESS = "0x32f236423928c2c138f46351d9e5fd26331b1aa4" -OLD_NOR_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" -OLD_SDVT_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" -OLD_SANDBOX_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" -OLD_ACCOUNTING_ORACLE_IMPL = "0x6aca050709469f1f98d8f40f68b1c83b533cd2b2" -CURATED_MODULE_ID = 1 -SIMPLE_DVT_MODULE_ID = 2 -AO_CONSENSUS_VERSION = 2 -VEBO_CONSENSUS_VERSION = 2 - -SR_VERSION = 2 -NOR_VERSION = 3 -DISTRIBUTED = 2 -SDVT_VERSION = 3 -AO_VERSION = 2 - -# new added fields -CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 -CURATED_MAX_DEPOSITS_PER_BLOCK = 150 -CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 -SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 -SDVT_MAX_DEPOSITS_PER_BLOCK = 50 -SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 - -old_nor_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -nor_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -# "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" -old_sdvt_uri = ( - "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -) -sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" -sandbox_uri = "0x697066733a516d5839414675394e456d76704b634336747a4a79684543316b7276344a5a72695767473951634d6e6e657a5165" - -CURATED_MODULE_BEFORE_VOTE = { - "id": 1, - "name": "curated-onchain-v1", - "stakingModuleFee": 500, - "treasuryFee": 500, - "targetShare": 10000, - "priorityExitShareThreshold": None, - "maxDepositsPerBlock": None, - "minDepositBlockDistance": None, -} - -SDVT_MODULE_BEFORE_VOTE = { - "id": 2, - "name": "SimpleDVT", - "stakingModuleAddress": "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", - "stakingModuleFee": 800, - "treasuryFee": 200, - "targetShare": 5000, - "priorityExitShareThreshold": None, - "maxDepositsPerBlock": None, - "minDepositBlockDistance": None, -} - -CURATED_MODULE_AFTER_VOTE = CURATED_MODULE_BEFORE_VOTE.copy() -CURATED_MODULE_AFTER_VOTE.update( - { - "priorityExitShareThreshold": CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, - "maxDepositsPerBlock": CURATED_MAX_DEPOSITS_PER_BLOCK, - "minDepositBlockDistance": CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, - } -) - -SDVT_MODULE_AFTER_VOTE = SDVT_MODULE_BEFORE_VOTE.copy() -SDVT_MODULE_AFTER_VOTE.update( - { - "priorityExitShareThreshold": SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS, - "maxDepositsPerBlock": SDVT_MAX_DEPOSITS_PER_BLOCK, - "minDepositBlockDistance": SDVT_MIN_DEPOSIT_BLOCK_DISTANCES, - } -) - -CS_MODULE_NAME = "Community Staking" -CS_STAKE_SHARE_LIMIT = 1000 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2000 -CS_STAKING_MODULE_FEE = 700 -CS_TREASURY_FEE = 300 -CS_MAX_DEPOSITS_PER_BLOCK = 30 -CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 63055 - -CSM_AFTER_VOTE = { - "id": 4, - "name": CS_MODULE_NAME, - "stakingModuleFee": CS_STAKING_MODULE_FEE, - "treasuryFee": CS_TREASURY_FEE, - "targetShare": CS_STAKE_SHARE_LIMIT, - "priorityExitShareThreshold": CS_PRIORITY_EXIT_SHARE_THRESHOLD, - "maxDepositsPerBlock": CS_MAX_DEPOSITS_PER_BLOCK, - "minDepositBlockDistance": CS_MIN_DEPOSIT_BLOCK_DISTANCE, -} - -OLD_SR_ABI = bi = [ - { - "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], - "name": "getStakingModule", - "outputs": [ - { - "components": [ - {"internalType": "uint24", "name": "id", "type": "uint24"}, - {"internalType": "address", "name": "stakingModuleAddress", "type": "address"}, - {"internalType": "uint16", "name": "stakingModuleFee", "type": "uint16"}, - {"internalType": "uint16", "name": "treasuryFee", "type": "uint16"}, - {"internalType": "uint16", "name": "stakeShareLimit", "type": "uint16"}, - {"internalType": "uint8", "name": "status", "type": "uint8"}, - {"internalType": "string", "name": "name", "type": "string"}, - {"internalType": "uint64", "name": "lastDepositAt", "type": "uint64"}, - {"internalType": "uint256", "name": "lastDepositBlock", "type": "uint256"}, - {"internalType": "uint256", "name": "exitedValidatorsCount", "type": "uint256"}, - ], - "internalType": "struct StakingRouter.StakingModule", - "name": "", - "type": "tuple", - } - ], - "stateMutability": "view", - "type": "function", - } -] - - -def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): - staking_router = contracts.staking_router - sr_proxy = interface.OssifiableProxy(contracts.staking_router) - locator_proxy = interface.OssifiableProxy(contracts.lido_locator) - nor_proxy = interface.AppProxyUpgradeable(contracts.node_operators_registry) - sdvt_proxy = interface.AppProxyUpgradeable(contracts.simple_dvt) - sandbox_proxy = interface.AppProxyUpgradeable(contracts.sandbox) - ao_proxy = interface.OssifiableProxy(contracts.accounting_oracle) - vebo_proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) - - assert staking_router.getStakingModulesCount() == 3 # curated + simpledvt + sandbox - - # Before voting tests - # locator - check_ossifiable_proxy_impl(locator_proxy, OLD_LOCATOR_IMPL_ADDRESS) - # DSM - check_dsm_roles_before_vote() - # SR - check_ossifiable_proxy_impl(sr_proxy, OLD_SR_IMPL_ADDRESS) - check_module_before_vote(CURATED_MODULE_BEFORE_VOTE) - check_module_before_vote(SDVT_MODULE_BEFORE_VOTE) - # NOR - nor_old_app = contracts.nor_app_repo.getLatest() - assert nor_proxy.implementation() == OLD_NOR_IMPL - assert_repo_before_vote(nor_old_app, 1, OLD_NOR_IMPL, old_nor_uri) - # SDVT - sdvt_old_app = contracts.simple_dvt_app_repo.getLatest() - assert sdvt_proxy.implementation() == OLD_SDVT_IMPL - assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, sdvt_uri) - # Sanbox - - sandbox_old_app = contracts.sandbox_repo.getLatest() - assert sandbox_proxy.implementation() == OLD_SANDBOX_IMPL - assert_repo_before_vote(sandbox_old_app, 1, OLD_SDVT_IMPL, sandbox_uri) - # AO - check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) - # no prermission to manage consensus version on agent - check_manage_consensus_role() - - # VEBO consensus version - assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 - - assert not contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) - assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) - - # had a role - # assert contracts.staking_router.hasRole(STAKING_MODULE_MANAGE_ROLE, contracts.agent.address) - - # START VOTE - if len(vote_ids_from_env) > 0: - (vote_id,) = vote_ids_from_env - else: - tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS, "priority_fee": get_priority_fee()} - vote_id, _ = start_vote(tx_params, silent=True) - - vote_tx = helpers.execute_vote(accounts, vote_id, contracts.voting) - - print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") - - assert staking_router.getStakingModulesCount() == 4 - - # locator - check_ossifiable_proxy_impl(locator_proxy, LIDO_LOCATOR_IMPL) - # DSM - check_dsm_roles_after_vote() - # SR - check_ossifiable_proxy_impl(sr_proxy, STAKING_ROUTER_IMPL) - check_module_after_vote(CURATED_MODULE_AFTER_VOTE) - check_module_after_vote(SDVT_MODULE_AFTER_VOTE) - # AO - check_ossifiable_proxy_impl(ao_proxy, ACCOUNTING_ORACLE_IMPL) - - # no permission to manage consensus version on agent - check_manage_consensus_role() - # VEBO consensus version - assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION - - assert contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) - assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) - - assert contracts.csmHashConsensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH - - # Events check - if bypass_events_decoding: - return - - events = group_voting_events_from_receipt(vote_tx) - - assert len(events) == 27 - - validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) - validate_dsm_roles_events(events) - validate_upgrade_events(events[4], STAKING_ROUTER_IMPL) - - validate_staking_module_update( - events[5], - [ - StakingModuleItem( - CURATED_MODULE_AFTER_VOTE["id"], - CURATED_MODULE_AFTER_VOTE["stakingModuleFee"], - CURATED_MODULE_AFTER_VOTE["targetShare"], - CURATED_MODULE_AFTER_VOTE["treasuryFee"], - CURATED_MODULE_AFTER_VOTE["priorityExitShareThreshold"], - CURATED_MODULE_AFTER_VOTE["maxDepositsPerBlock"], - CURATED_MODULE_AFTER_VOTE["minDepositBlockDistance"], - ), - StakingModuleItem( - SDVT_MODULE_AFTER_VOTE["id"], - SDVT_MODULE_AFTER_VOTE["stakingModuleFee"], - SDVT_MODULE_AFTER_VOTE["targetShare"], - SDVT_MODULE_AFTER_VOTE["treasuryFee"], - SDVT_MODULE_AFTER_VOTE["priorityExitShareThreshold"], - SDVT_MODULE_AFTER_VOTE["maxDepositsPerBlock"], - SDVT_MODULE_AFTER_VOTE["minDepositBlockDistance"], - ), - ], - ) - - nor_new_app = contracts.nor_app_repo.getLatest() - assert_repo_update(nor_new_app, nor_old_app, NODE_OPERATORS_REGISTRY_IMPL, nor_uri) - validate_repo_upgrade_event(events[6], RepoUpgrade(2, nor_new_app[0])) - validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL) - validate_nor_update(events[8], NOR_VERSION) - - sdvt_new_app = contracts.simple_dvt_app_repo.getLatest() - assert_repo_update(sdvt_new_app, sdvt_old_app, SIMPLE_DVT_IMPL, sdvt_uri) - validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) - validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL) - validate_nor_update(events[11], SDVT_VERSION) - - sandbox_new_app = contracts.sandbox_repo.getLatest() - assert_repo_update(sandbox_new_app, sandbox_old_app, SANDBOX_IMPL, sandbox_uri) - validate_repo_upgrade_event(events[12], RepoUpgrade(2, sandbox_new_app[0])) - # validate_app_update_event(events[13], SANDBOX_DVT_ARAGON_APP_ID, SANDBOX_DVT_IMPL) - # validate_nor_update(events[14], SANDBOX_VERSION) - - # AO - validate_upgrade_events(events[15], ACCOUNTING_ORACLE_IMPL) - validate_ao_update(events[16], AO_VERSION, AO_CONSENSUS_VERSION) - - validate_grant_role_event( - events[17], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address - ) - - validate_vebo_consensus_version_set(events[18]) - - validate_revoke_role_event( - events[19], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address - ) - - # 20 - add of staking module - - # validate_module_add(events[20], CSM_AFTER_VOTE) - validate_grant_role_event(events[21], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, contracts.agent.address) - validate_grant_role_event(events[22], RESUME_ROLE, contracts.agent.address, contracts.agent.address) - - validate_resume_event(events[23]) - validate_revoke_role_event(events[24], RESUME_ROLE, contracts.agent.address, contracts.agent.address) - validate_updateInitial_epoch(events[25]) - - check_csm() - - -def check_ossifiable_proxy_impl(proxy, expected_impl): - current_impl_address = proxy.proxy__getImplementation() - assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" - - -def check_dsm_roles_before_vote(): - new_dsm_doesnt_have_unvet_role = contracts.staking_router.hasRole( - STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module - ) - assert not new_dsm_doesnt_have_unvet_role - - old_dsm_has_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) - - assert old_dsm_has_pause_role - old_dsm_has_resume_role = contracts.staking_router.hasRole( - STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 - ) - - assert old_dsm_has_resume_role - - -def check_dsm_roles_after_vote(): - new_dsm_has_unvet_role = contracts.staking_router.hasRole( - STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module - ) - assert new_dsm_has_unvet_role - - old_dsm_doesnt_have_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) - assert not old_dsm_doesnt_have_pause_role - - old_dsm_doesnt_have_resume_role = contracts.staking_router.hasRole( - STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 - ) - assert not old_dsm_doesnt_have_resume_role - - -def check_manage_consensus_role(): - agent_has_manage_consensus_role = contracts.validators_exit_bus_oracle.hasRole( - MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address - ) - assert not agent_has_manage_consensus_role - - -def check_module_before_vote(expected_module_data: Dict): - sr_contract = Contract.from_abi("StakingContract", contracts.staking_router.address, OLD_SR_ABI) - module = sr_contract.getStakingModule(expected_module_data["id"]) - assert module["id"] == expected_module_data["id"] - assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] - assert module["treasuryFee"] == expected_module_data["treasuryFee"] - assert module["stakeShareLimit"] == expected_module_data["targetShare"] - assert "priorityExitShareThreshold" not in module - assert "maxDepositsPerBlock" not in module - assert "minDepositBlockDistance" not in module - - -def check_module_after_vote(expected_module_data: Dict): - module = contracts.staking_router.getStakingModule(expected_module_data["id"]) - assert module["id"] == expected_module_data["id"] - assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] - assert module["treasuryFee"] == expected_module_data["treasuryFee"] - assert module["stakeShareLimit"] == expected_module_data["targetShare"] - assert module["priorityExitShareThreshold"] == expected_module_data["priorityExitShareThreshold"] - assert module["maxDepositsPerBlock"] == expected_module_data["maxDepositsPerBlock"] - assert module["minDepositBlockDistance"] == expected_module_data["minDepositBlockDistance"] - - -def assert_repo_before_vote(old_app, version, contract_address, old_content_uri): - assert old_app[0][0] == version - assert old_app[2] == old_content_uri, "Content uri before vote is wrong" - assert old_app[1] == contract_address, "New address should match" - - -def assert_repo_update(new_app, old_app, contract_address, old_content_uri): - assert old_app[1] != new_app[1], "Address should change" - assert new_app[1] == contract_address, "New address should match" - assert new_app[0][0] == old_app[0][0] + 1, "Major version should increment" - assert old_app[2] == new_app[2], "Content uri should not be changed" - assert new_app[2] == old_content_uri, "Content uri should match" - - -def check_csm(): - cs = contracts.staking_router.getStakingModule(4) - - assert cs["name"] == CSM_AFTER_VOTE["name"] - assert cs["stakingModuleFee"] == CSM_AFTER_VOTE["stakingModuleFee"] - assert cs["treasuryFee"] == CSM_AFTER_VOTE["treasuryFee"] - assert cs["stakeShareLimit"] == CSM_AFTER_VOTE["targetShare"] - assert cs["priorityExitShareThreshold"] == CSM_AFTER_VOTE["priorityExitShareThreshold"] - assert cs["maxDepositsPerBlock"] == CSM_AFTER_VOTE["maxDepositsPerBlock"] - assert cs["minDepositBlockDistance"] == CSM_AFTER_VOTE["minDepositBlockDistance"] - - -# Events check - - -def validate_upgrade_events(events: EventDict, implementation: str): - _events_chain = ["LogScriptCall", "LogScriptCall", "Upgraded", "ScriptResult"] - validate_events_chain([e.name for e in events], _events_chain) - assert events.count("Upgraded") == 1 - assert events["Upgraded"]["implementation"] == implementation, "Wrong withdrawal vault proxy implementation" - - -def validate_dsm_roles_events(events: EventDict): - validate_revoke_role_event( - events[1], PAUSE_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address - ) - validate_revoke_role_event( - events[2], STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address - ) - - validate_grant_role_event( - events[3], STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module.address, contracts.agent.address - ) - - -def validate_staking_module_update(event: EventDict, module_items: List[StakingModuleItem]): - - assert len(module_items) == 2 - - _events_chain = [ - "LogScriptCall", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "ContractVersionSet", - ] - - validate_events_chain([e.name for e in event], _events_chain) - - assert event.count("StakingModuleFeesSet") == 3 - assert event.count("StakingModuleShareLimitSet") == 3 - assert event.count("StakingModuleMinDepositBlockDistanceSet") == 3 - assert event.count("StakingModuleMaxDepositsPerBlockSet") == 3 - assert event.count("ContractVersionSet") == 1 - - # curated - assert event["StakingModuleShareLimitSet"][0]["stakingModuleId"] == module_items[0].id - assert event["StakingModuleShareLimitSet"][0]["stakeShareLimit"] == module_items[0].stake_share_limit - assert ( - event["StakingModuleShareLimitSet"][0]["priorityExitShareThreshold"] - == module_items[0].priority_exit_share_threshold - ) - assert event["StakingModuleFeesSet"][0]["stakingModuleId"] == module_items[0].id - assert event["StakingModuleFeesSet"][0]["stakingModuleFee"] == module_items[0].staking_module_fee - assert event["StakingModuleFeesSet"][0]["treasuryFee"] == module_items[0].treasury_fee - - assert ( - event["StakingModuleMaxDepositsPerBlockSet"][0]["maxDepositsPerBlock"] == module_items[0].max_deposits_per_block - ) - - assert ( - event["StakingModuleMinDepositBlockDistanceSet"][0]["minDepositBlockDistance"] - == module_items[0].min_deposit_block_distance - ) - - assert event["ContractVersionSet"]["version"] == SR_VERSION - - assert event["StakingModuleShareLimitSet"][1]["stakingModuleId"] == module_items[1].id - assert event["StakingModuleShareLimitSet"][1]["stakeShareLimit"] == module_items[1].stake_share_limit - assert ( - event["StakingModuleShareLimitSet"][1]["priorityExitShareThreshold"] - == module_items[1].priority_exit_share_threshold - ) - assert event["StakingModuleFeesSet"][1]["stakingModuleId"] == module_items[1].id - assert event["StakingModuleFeesSet"][1]["stakingModuleFee"] == module_items[1].staking_module_fee - assert event["StakingModuleFeesSet"][1]["treasuryFee"] == module_items[1].treasury_fee - - assert ( - event["StakingModuleMaxDepositsPerBlockSet"][1]["maxDepositsPerBlock"] == module_items[1].max_deposits_per_block - ) - - assert ( - event["StakingModuleMinDepositBlockDistanceSet"][1]["minDepositBlockDistance"] - == module_items[1].min_deposit_block_distance - ) - - -def validate_nor_update(event: EventDict, version): - _events_chain = [ - "LogScriptCall", - "ContractVersionSet", - "RewardDistributionStateChanged", - ] - validate_events_chain([e.name for e in event], _events_chain) - - assert event["ContractVersionSet"]["version"] == version - assert event["RewardDistributionStateChanged"]["state"] == DISTRIBUTED - - -def validate_ao_update(event: EventDict, version, ao_consensus_version): - _events_chain = [ - "LogScriptCall", - "ContractVersionSet", - "ConsensusVersionSet", - ] - validate_events_chain([e.name for e in event], _events_chain) - - assert event["ContractVersionSet"]["version"] == version - assert event["ConsensusVersionSet"]["version"] == ao_consensus_version - assert event["ConsensusVersionSet"]["prevVersion"] == ao_consensus_version - 1 - - -def validate_vebo_consensus_version_set(event: EventDict): - _events_chain = ["LogScriptCall", "LogScriptCall", "ConsensusVersionSet", "ScriptResult"] - validate_events_chain([e.name for e in event], _events_chain) - assert event["ConsensusVersionSet"]["version"] == VEBO_CONSENSUS_VERSION - - -def validate_resume_event(event: EventDict): - _events_chain = ["LogScriptCall", "LogScriptCall", "Resumed", "ScriptResult"] - validate_events_chain([e.name for e in event], _events_chain) - assert event.count("Resumed") == 1 - - -def validate_updateInitial_epoch(event: EventDict): - _events_chain = ["LogScriptCall", "LogScriptCall", "FrameConfigSet", "ScriptResult"] - validate_events_chain([e.name for e in event], _events_chain) - assert event["FrameConfigSet"]["newInitialEpoch"] == CS_ORACLE_INITIAL_EPOCH - - -def validate_module_add(event, csm): - _events_chain = [ - "LogScriptCall", - "StakingRouterETHDeposited", - "StakingModuleAdded", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "ScriptResult", - ] - validate_events_chain([e.name for e in event], _events_chain) diff --git a/tests/test_vote_sr_v2_mainnet.py b/tests/test_vote_sr_v2_mainnet.py index 6a4fab813..fc74cdc00 100644 --- a/tests/test_vote_sr_v2_mainnet.py +++ b/tests/test_vote_sr_v2_mainnet.py @@ -6,10 +6,13 @@ LIDO_LOCATOR_IMPL, NODE_OPERATORS_REGISTRY_IMPL, NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + NODE_OPERATORS_REGISTRY, + SIMPLE_DVT, SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL, ACCOUNTING_ORACLE_IMPL, CS_ACCOUNTING_ADDRESS, + CSM, ) from scripts.mainnet.vote_sr_v2_mainnet import start_vote from utils.config import ( @@ -33,6 +36,8 @@ class StakingModuleItem(NamedTuple): id: int + staking_module_address: str + name: str staking_module_fee: int stake_share_limit: int treasury_fee: int @@ -80,6 +85,7 @@ class StakingModuleItem(NamedTuple): CURATED_MODULE_BEFORE_VOTE = { "id": 1, "name": "curated-onchain-v1", + "stakingModuleAddress": NODE_OPERATORS_REGISTRY, "stakingModuleFee": 500, "treasuryFee": 500, "targetShare": 10000, @@ -91,7 +97,7 @@ class StakingModuleItem(NamedTuple): SDVT_MODULE_BEFORE_VOTE = { "id": 2, "name": "SimpleDVT", - "stakingModuleAddress": "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "stakingModuleAddress": SIMPLE_DVT, "stakingModuleFee": 800, "treasuryFee": 200, "targetShare": 50, @@ -128,8 +134,9 @@ class StakingModuleItem(NamedTuple): CS_ORACLE_INITIAL_EPOCH = 58050 CSM_AFTER_VOTE = { - "id": 4, + "id": 3, "name": CS_MODULE_NAME, + "stakingModuleAddress": CSM, "stakingModuleFee": CS_STAKING_MODULE_FEE, "treasuryFee": CS_TREASURY_FEE, "targetShare": CS_STAKE_SHARE_LIMIT, @@ -246,6 +253,8 @@ def test_vote( assert contracts.csmHashConsensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + check_csm() + # Events check # events = group_voting_events(vote_tx) events = group_voting_events_from_receipt(vote_tx) @@ -261,6 +270,8 @@ def test_vote( [ StakingModuleItem( CURATED_MODULE_AFTER_VOTE["id"], + CURATED_MODULE_AFTER_VOTE["stakingModuleAddress"], + CURATED_MODULE_AFTER_VOTE["name"], CURATED_MODULE_AFTER_VOTE["stakingModuleFee"], CURATED_MODULE_AFTER_VOTE["targetShare"], CURATED_MODULE_AFTER_VOTE["treasuryFee"], @@ -270,6 +281,8 @@ def test_vote( ), StakingModuleItem( SDVT_MODULE_AFTER_VOTE["id"], + SDVT_MODULE_AFTER_VOTE["stakingModuleAddress"], + SDVT_MODULE_AFTER_VOTE["name"], SDVT_MODULE_AFTER_VOTE["stakingModuleFee"], SDVT_MODULE_AFTER_VOTE["targetShare"], SDVT_MODULE_AFTER_VOTE["treasuryFee"], @@ -316,17 +329,26 @@ def test_vote( ), ) - # 20 - add of staking module - - # validate_module_add(events[19], CSM_AFTER_VOTE) + validate_module_add( + events[19], + StakingModuleItem( + CSM_AFTER_VOTE["id"], + CSM_AFTER_VOTE["stakingModuleAddress"], + CSM_AFTER_VOTE["name"], + CSM_AFTER_VOTE["stakingModuleFee"], + CSM_AFTER_VOTE["targetShare"], + CSM_AFTER_VOTE["treasuryFee"], + CSM_AFTER_VOTE["priorityExitShareThreshold"], + CSM_AFTER_VOTE["maxDepositsPerBlock"], + CSM_AFTER_VOTE["minDepositBlockDistance"], + ), + ) validate_grant_role_event(events[20], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, contracts.agent.address) validate_grant_role_event(events[21], RESUME_ROLE, contracts.agent.address, contracts.agent.address) validate_resume_event(events[22]) validate_revoke_role_event(events[23], RESUME_ROLE, contracts.agent.address, contracts.agent.address) - # validate_updateInitial_epoch(events[24]) - - # check_csm() + validate_updateInitial_epoch(events[24]) def check_ossifiable_proxy_impl(proxy, expected_impl): @@ -542,11 +564,13 @@ def validate_updateInitial_epoch(event: EventDict): assert event["FrameConfigSet"]["newInitialEpoch"] == CS_ORACLE_INITIAL_EPOCH -def validate_module_add(event, csm): +def validate_module_add(event, csm: StakingModuleItem): _events_chain = [ + "LogScriptCall", "LogScriptCall", "StakingRouterETHDeposited", "StakingModuleAdded", + "StakingModuleShareLimitSet", "StakingModuleFeesSet", "StakingModuleMaxDepositsPerBlockSet", "StakingModuleMinDepositBlockDistanceSet", @@ -554,6 +578,24 @@ def validate_module_add(event, csm): ] validate_events_chain([e.name for e in event], _events_chain) + assert event["StakingRouterETHDeposited"]["stakingModuleId"] == csm.id + assert event["StakingRouterETHDeposited"]["amount"] == 0 + assert event["StakingModuleAdded"]["stakingModuleId"] == csm.id + assert event["StakingModuleAdded"]["stakingModule"] == csm.staking_module_address + assert event["StakingModuleAdded"]["name"] == csm.name + + assert event["StakingModuleShareLimitSet"]["stakingModuleId"] == csm.id + assert event["StakingModuleShareLimitSet"]["stakeShareLimit"] == csm.stake_share_limit + assert event["StakingModuleShareLimitSet"]["priorityExitShareThreshold"] == csm.priority_exit_share_threshold + + assert event["StakingModuleFeesSet"]["stakingModuleId"] == csm.id + assert event["StakingModuleFeesSet"]["stakingModuleFee"] == csm.staking_module_fee + assert event["StakingModuleFeesSet"]["treasuryFee"] == csm.treasury_fee + + assert event["StakingModuleMaxDepositsPerBlockSet"]["maxDepositsPerBlock"] == csm.max_deposits_per_block + + assert event["StakingModuleMinDepositBlockDistanceSet"]["minDepositBlockDistance"] == csm.min_deposit_block_distance + def check_csm(): cs = contracts.staking_router.getStakingModule(3) From cd938b62e9e40bd8d9b7c331ca3f56a6e4072d3c Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 5 Jul 2024 01:44:34 +0400 Subject: [PATCH 075/220] fix: csm factory event check --- archive/scripts/vote_sr_v2_holesky.py | 398 +++++++++++++++ archive/tests/test_vote_sr_v2_holesky.py | 577 ++++++++++++++++++++++ scripts/mainnet/vote_sr_v2_mainnet.py | 18 +- tests/test_vote_sr_v2_mainnet.py | 14 +- utils/test/event_validators/easy_track.py | 6 +- 5 files changed, 999 insertions(+), 14 deletions(-) create mode 100644 archive/scripts/vote_sr_v2_holesky.py create mode 100644 archive/tests/test_vote_sr_v2_holesky.py diff --git a/archive/scripts/vote_sr_v2_holesky.py b/archive/scripts/vote_sr_v2_holesky.py new file mode 100644 index 000000000..ee64c8aeb --- /dev/null +++ b/archive/scripts/vote_sr_v2_holesky.py @@ -0,0 +1,398 @@ +""" +SR V2 +1. Update locator implementation +2. Revoke pause role from old DSM +3. Revoke resume role from old DSM +4. Grant unvetting role to new DSM +5. Update SR implementation +6. Call finalize upgrade on SR +7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo +8. Update `NodeOperatorsRegistry` implementation +9. Finalize NOR upgrade +10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo +11. Update `SimpleDVT` implementation +12. Finalize SimpleDVT upgrade +13. Publish new `Sandbox` implementation in Sandbox app APM repo +14. Update `Sandbox` implementation +15. Finalize Sandbox upgrade +16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, +17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +18. Grant manage consensus role to agent ${AGENT}` +19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` +20. Revoke manage consensus role from agent ${AGENT}" + +CSM + +21. Add staking module +22. Grant request burn role to CSAccounting contract +23. Grant resume role to agent +24. Resume staking module +25. Revoke resume role from agent +26. Update initial epoch +27. Add CS settle EL stealing factory to ET +""" + +import time + +try: + from brownie import interface, accounts +except ImportError: + print("You're probably running inside Brownie console. Please call:") + print("set_console_globals(interface=interface)") + + +from typing import Dict, Tuple, Optional +from utils.config import ( + get_deployer_account, + get_is_live, + get_priority_fee, + contracts, + NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + SIMPLE_DVT_ARAGON_APP_ID, + SANDBOX_APP_ID, + LIDO_LOCATOR_IMPL, + STAKING_ROUTER_IMPL, + ACCOUNTING_ORACLE_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, + CS_ACCOUNTING_ADDRESS, +) +from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description +from utils.repo import ( + add_implementation_to_nor_app_repo, + add_implementation_to_sdvt_app_repo, + add_implementation_to_sandbox_app_repo, +) +from utils.permissions import encode_oz_grant_role, encode_oz_revoke_role +from utils.easy_track import add_evmscript_factory, create_permissions +from utils.kernel import update_app_implementation +from utils.voting import bake_vote_items, confirm_vote_script, create_vote + +from brownie.network.transaction import TransactionReceipt +from utils.agent import agent_forward + + +# SR +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000, 10_000] +MAX_DEPOSITS_PER_BLOCK = [150, 50, 50] +MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25, 25] +NOR_VERSION = ["2", "0", "0"] +SDVT_VERSION = ["2", "0", "0"] +SANDBOX_VERSION = ["2", "0", "0"] +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 + +# CSM +CS_MODULE_NAME = "Community Staking" +CS_STAKE_SHARE_LIMIT = 1000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2000 +CS_STAKING_MODULE_FEE = 700 +CS_TREASURY_FEE = 300 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 63055 + +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0x07696EA8A5b53C3E35d9cce10cc62c6c79C4691D" + + +description = """ +Proposal to support DSM 2.0 and CSM Module +""" + + +def encode_locator_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.lido_locator) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_staking_router_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.staking_router) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_staking_router_finalize() -> Tuple[str, str]: + proxy = interface.StakingRouter(contracts.staking_router) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input( + PRIORITY_EXIT_SHARE_THRESHOLDS_BP, MAX_DEPOSITS_PER_BLOCK, MIN_DEPOSIT_BLOCK_DISTANCES + ) + + +def encode_nor_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.node_operators_registry) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_sdvt_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.simple_dvt) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_sandbox_finalize() -> Tuple[str, str]: + proxy = interface.NodeOperatorsRegistry(contracts.sandbox) + return proxy.address, proxy.finalizeUpgrade_v3.encode_input() + + +def encode_ao_proxy_update(implementation: str) -> Tuple[str, str]: + proxy = interface.OssifiableProxy(contracts.accounting_oracle) + return proxy.address, proxy.proxy__upgradeTo.encode_input(implementation) + + +def encode_ao_finalize() -> Tuple[str, str]: + proxy = interface.AccountingOracle(contracts.accounting_oracle) + return proxy.address, proxy.finalizeUpgrade_v2.encode_input(AO_CONSENSUS_VERSION) + + +def encode_set_consensus_version() -> Tuple[str, str]: + proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) + return proxy.address, proxy.setConsensusVersion.encode_input(VEBO_CONSENSUS_VERSION) + + +def get_repo_uri(repo_address: str) -> str: + contract = interface.Repo(repo_address).getLatest() + return contract["contentURI"] + + +def get_repo_version(repo_address: str) -> tuple[int, int, int]: + contract = interface.Repo(repo_address).getLatest() + return contract["semanticVersion"] + + +def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: + """Prepare and run voting.""" + nor_repo = contracts.nor_app_repo.address + simple_dvt_repo = contracts.simple_dvt_app_repo.address + sandbox_repo = contracts.sandbox_repo.address + + nor_uri = get_repo_uri(nor_repo) + simple_dvt_uri = get_repo_uri(simple_dvt_repo) + sandbox_uri = get_repo_uri(sandbox_repo) + + vote_desc_items, call_script_items = zip( + # + # SR 2 + # + ( + "1. Update locator implementation", + agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), + ), + ( + "2. Revoke pause role from old DSM", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_PAUSE_ROLE", + revoke_from=contracts.deposit_security_module_v2, + ) + ] + ), + ), + ( + "3. Revoke resume role from old DSM", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_RESUME_ROLE", + revoke_from=contracts.deposit_security_module_v2, + ) + ] + ), + ), + ( + "4. Grant unvetting role to new DSM", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.staking_router, + role_name="STAKING_MODULE_UNVETTING_ROLE", + grant_to=contracts.deposit_security_module, + ) + ] + ), + ), + ( + "5. Update SR implementation", + agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), + ), + ( + "6. Call finalize upgrade on SR", + encode_staking_router_finalize(), + ), + ( + "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), + ), + ( + "8. Update `NodeOperatorsRegistry` implementation", + update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + ), + ( + "9. Finalize NOR upgrade", + encode_nor_finalize(), + ), + ( + "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", + add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), + ), + ( + "11. Update `SimpleDVT` implementation", + update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + ), + ( + "12. Finalize SimpleDVT upgrade", + encode_sdvt_finalize(), + ), + ( + "13. Publish new `Sandbox` implementation in Sandbox app APM repo", + add_implementation_to_sandbox_app_repo(SANDBOX_VERSION, NODE_OPERATORS_REGISTRY_IMPL, sandbox_uri), + ), + ( + "14. Update `Sandbox` implementation", + update_app_implementation(SANDBOX_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), + ), + ( + "15. Finalize Sandbox upgrade", + encode_sandbox_finalize(), + ), + ( + "16. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), + ), + ( + "17. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + encode_ao_finalize(), + ), + ( + "18. Grant manage consensus role to agent ${AGENT}", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.validators_exit_bus_oracle, + role_name="MANAGE_CONSENSUS_VERSION_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "19. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + agent_forward([encode_set_consensus_version()]), + ), + ( + "20. Revoke manage consensus role from agent ${AGENT}", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.validators_exit_bus_oracle, + role_name="MANAGE_CONSENSUS_VERSION_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + # + # CSM + # + ( + "21. Add staking module", + agent_forward( + [ + ( + contracts.staking_router.address, + contracts.staking_router.addStakingModule.encode_input( + CS_MODULE_NAME, + contracts.csm.address, + CS_STAKE_SHARE_LIMIT, + CS_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_STAKING_MODULE_FEE, + CS_TREASURY_FEE, + CS_MAX_DEPOSITS_PER_BLOCK, + CS_MIN_DEPOSIT_BLOCK_DISTANCE, + ), + ), + ] + ), + ), + ( + "22. Grant request burn role to CSAccounting contract", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.burner, + role_name="REQUEST_BURN_SHARES_ROLE", + grant_to=CS_ACCOUNTING_ADDRESS, + ) + ] + ), + ), + ( + "23. Grant resume role to agent", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.csm, + role_name="RESUME_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "24. Resume staking module", + agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), + ), + ( + "25. Revoke resume role from agent", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.csm, + role_name="RESUME_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), + ( + "26. Update initial epoch", + agent_forward( + [ + ( + contracts.csmHashConsensus.address, + contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), + ) + ] + ), + ), + ( + "27. Add CS settle EL stealing factory to ET", + add_evmscript_factory( + factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, + permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), + ), + ), + ) + + vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) + + if silent: + desc_ipfs = calculate_vote_ipfs_description(description) + else: + desc_ipfs = upload_vote_ipfs_description(description) + + return confirm_vote_script(vote_items, silent, desc_ipfs) and list( + create_vote(vote_items, tx_params, desc_ipfs=desc_ipfs) + ) + + +def main(): + tx_params = {"from": get_deployer_account()} + + if get_is_live(): + tx_params["priority_fee"] = get_priority_fee() + + vote_id, _ = start_vote(tx_params=tx_params, silent=True) # disable IPFS description for Holesky + + vote_id >= 0 and print(f"Vote created: {vote_id}.") + + time.sleep(10) # hack for waiting thread #2. diff --git a/archive/tests/test_vote_sr_v2_holesky.py b/archive/tests/test_vote_sr_v2_holesky.py new file mode 100644 index 000000000..7448f8da4 --- /dev/null +++ b/archive/tests/test_vote_sr_v2_holesky.py @@ -0,0 +1,577 @@ +import pytest + +from utils.config import ( + contracts, + get_priority_fee, + STAKING_ROUTER_IMPL, + LIDO_LOCATOR_IMPL, + NODE_OPERATORS_REGISTRY_IMPL, + NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, + SIMPLE_DVT_ARAGON_APP_ID, + SIMPLE_DVT_IMPL, + ACCOUNTING_ORACLE_IMPL, + SANDBOX_IMPL, + CS_ACCOUNTING_ADDRESS, +) +from scripts.holesky.vote_sr_v2_holesky import start_vote +from utils.config import ( + contracts, + LDO_HOLDER_ADDRESS_FOR_TESTS, +) +from brownie import interface, Contract +from utils.test.tx_tracing_helpers import * +from utils.test.event_validators.permission import validate_grant_role_event, validate_revoke_role_event +from utils.test.event_validators.common import validate_events_chain +from utils.test.event_validators.repo_upgrade import validate_repo_upgrade_event, RepoUpgrade +from utils.test.event_validators.aragon import validate_app_update_event +from typing import NamedTuple + + +class StakingModuleItem(NamedTuple): + id: int + staking_module_fee: int + stake_share_limit: int + treasury_fee: int + priority_exit_share_threshold: int + max_deposits_per_block: int + min_deposit_block_distance: int + + +STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" +PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" +STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" +MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" +STAKING_MODULE_MANAGE_ROLE = "0x3105bcbf19d4417b73ae0e58d508a65ecf75665e46c2622d8521732de6080c48" +REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" +RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" +OLD_LOCATOR_IMPL_ADDRESS = "0xDba5Ad530425bb1b14EECD76F1b4a517780de537" +OLD_SR_IMPL_ADDRESS = "0x32f236423928c2c138f46351d9e5fd26331b1aa4" +OLD_NOR_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" +OLD_SDVT_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" +OLD_SANDBOX_IMPL = "0xe0270cf2564d81e02284e16539f59c1b5a4718fe" +OLD_ACCOUNTING_ORACLE_IMPL = "0x6aca050709469f1f98d8f40f68b1c83b533cd2b2" +CURATED_MODULE_ID = 1 +SIMPLE_DVT_MODULE_ID = 2 +AO_CONSENSUS_VERSION = 2 +VEBO_CONSENSUS_VERSION = 2 + +SR_VERSION = 2 +NOR_VERSION = 3 +DISTRIBUTED = 2 +SDVT_VERSION = 3 +AO_VERSION = 2 + +# new added fields +CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 +CURATED_MAX_DEPOSITS_PER_BLOCK = 150 +CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 +SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 +SDVT_MAX_DEPOSITS_PER_BLOCK = 50 +SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 + +old_nor_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +nor_uri = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +# "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" +old_sdvt_uri = ( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +) +sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" +sandbox_uri = "0x697066733a516d5839414675394e456d76704b634336747a4a79684543316b7276344a5a72695767473951634d6e6e657a5165" + +CURATED_MODULE_BEFORE_VOTE = { + "id": 1, + "name": "curated-onchain-v1", + "stakingModuleFee": 500, + "treasuryFee": 500, + "targetShare": 10000, + "priorityExitShareThreshold": None, + "maxDepositsPerBlock": None, + "minDepositBlockDistance": None, +} + +SDVT_MODULE_BEFORE_VOTE = { + "id": 2, + "name": "SimpleDVT", + "stakingModuleAddress": "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433", + "stakingModuleFee": 800, + "treasuryFee": 200, + "targetShare": 5000, + "priorityExitShareThreshold": None, + "maxDepositsPerBlock": None, + "minDepositBlockDistance": None, +} + +CURATED_MODULE_AFTER_VOTE = CURATED_MODULE_BEFORE_VOTE.copy() +CURATED_MODULE_AFTER_VOTE.update( + { + "priorityExitShareThreshold": CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, + "maxDepositsPerBlock": CURATED_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, + } +) + +SDVT_MODULE_AFTER_VOTE = SDVT_MODULE_BEFORE_VOTE.copy() +SDVT_MODULE_AFTER_VOTE.update( + { + "priorityExitShareThreshold": SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS, + "maxDepositsPerBlock": SDVT_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": SDVT_MIN_DEPOSIT_BLOCK_DISTANCES, + } +) + +CS_MODULE_NAME = "Community Staking" +CS_STAKE_SHARE_LIMIT = 1000 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2000 +CS_STAKING_MODULE_FEE = 700 +CS_TREASURY_FEE = 300 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 63055 + +CSM_AFTER_VOTE = { + "id": 4, + "name": CS_MODULE_NAME, + "stakingModuleFee": CS_STAKING_MODULE_FEE, + "treasuryFee": CS_TREASURY_FEE, + "targetShare": CS_STAKE_SHARE_LIMIT, + "priorityExitShareThreshold": CS_PRIORITY_EXIT_SHARE_THRESHOLD, + "maxDepositsPerBlock": CS_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": CS_MIN_DEPOSIT_BLOCK_DISTANCE, +} + +OLD_SR_ABI = bi = [ + { + "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], + "name": "getStakingModule", + "outputs": [ + { + "components": [ + {"internalType": "uint24", "name": "id", "type": "uint24"}, + {"internalType": "address", "name": "stakingModuleAddress", "type": "address"}, + {"internalType": "uint16", "name": "stakingModuleFee", "type": "uint16"}, + {"internalType": "uint16", "name": "treasuryFee", "type": "uint16"}, + {"internalType": "uint16", "name": "stakeShareLimit", "type": "uint16"}, + {"internalType": "uint8", "name": "status", "type": "uint8"}, + {"internalType": "string", "name": "name", "type": "string"}, + {"internalType": "uint64", "name": "lastDepositAt", "type": "uint64"}, + {"internalType": "uint256", "name": "lastDepositBlock", "type": "uint256"}, + {"internalType": "uint256", "name": "exitedValidatorsCount", "type": "uint256"}, + ], + "internalType": "struct StakingRouter.StakingModule", + "name": "", + "type": "tuple", + } + ], + "stateMutability": "view", + "type": "function", + } +] + + +def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): + staking_router = contracts.staking_router + sr_proxy = interface.OssifiableProxy(contracts.staking_router) + locator_proxy = interface.OssifiableProxy(contracts.lido_locator) + nor_proxy = interface.AppProxyUpgradeable(contracts.node_operators_registry) + sdvt_proxy = interface.AppProxyUpgradeable(contracts.simple_dvt) + sandbox_proxy = interface.AppProxyUpgradeable(contracts.sandbox) + ao_proxy = interface.OssifiableProxy(contracts.accounting_oracle) + vebo_proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) + + assert staking_router.getStakingModulesCount() == 3 # curated + simpledvt + sandbox + + # Before voting tests + # locator + check_ossifiable_proxy_impl(locator_proxy, OLD_LOCATOR_IMPL_ADDRESS) + # DSM + check_dsm_roles_before_vote() + # SR + check_ossifiable_proxy_impl(sr_proxy, OLD_SR_IMPL_ADDRESS) + check_module_before_vote(CURATED_MODULE_BEFORE_VOTE) + check_module_before_vote(SDVT_MODULE_BEFORE_VOTE) + # NOR + nor_old_app = contracts.nor_app_repo.getLatest() + assert nor_proxy.implementation() == OLD_NOR_IMPL + assert_repo_before_vote(nor_old_app, 1, OLD_NOR_IMPL, old_nor_uri) + # SDVT + sdvt_old_app = contracts.simple_dvt_app_repo.getLatest() + assert sdvt_proxy.implementation() == OLD_SDVT_IMPL + assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, sdvt_uri) + # Sanbox + + sandbox_old_app = contracts.sandbox_repo.getLatest() + assert sandbox_proxy.implementation() == OLD_SANDBOX_IMPL + assert_repo_before_vote(sandbox_old_app, 1, OLD_SDVT_IMPL, sandbox_uri) + # AO + check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) + # no prermission to manage consensus version on agent + check_manage_consensus_role() + + # VEBO consensus version + assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 + + assert not contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) + + # had a role + # assert contracts.staking_router.hasRole(STAKING_MODULE_MANAGE_ROLE, contracts.agent.address) + + # START VOTE + if len(vote_ids_from_env) > 0: + (vote_id,) = vote_ids_from_env + else: + tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS, "priority_fee": get_priority_fee()} + vote_id, _ = start_vote(tx_params, silent=True) + + vote_tx = helpers.execute_vote(accounts, vote_id, contracts.voting) + + print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") + + assert staking_router.getStakingModulesCount() == 4 + + # locator + check_ossifiable_proxy_impl(locator_proxy, LIDO_LOCATOR_IMPL) + # DSM + check_dsm_roles_after_vote() + # SR + check_ossifiable_proxy_impl(sr_proxy, STAKING_ROUTER_IMPL) + check_module_after_vote(CURATED_MODULE_AFTER_VOTE) + check_module_after_vote(SDVT_MODULE_AFTER_VOTE) + # AO + check_ossifiable_proxy_impl(ao_proxy, ACCOUNTING_ORACLE_IMPL) + + # no permission to manage consensus version on agent + check_manage_consensus_role() + # VEBO consensus version + assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION + + assert contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) + + assert contracts.csmHashConsensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + + # Events check + if bypass_events_decoding: + return + + events = group_voting_events_from_receipt(vote_tx) + + assert len(events) == 27 + + validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) + validate_dsm_roles_events(events) + validate_upgrade_events(events[4], STAKING_ROUTER_IMPL) + + validate_staking_module_update( + events[5], + [ + StakingModuleItem( + CURATED_MODULE_AFTER_VOTE["id"], + CURATED_MODULE_AFTER_VOTE["stakingModuleFee"], + CURATED_MODULE_AFTER_VOTE["targetShare"], + CURATED_MODULE_AFTER_VOTE["treasuryFee"], + CURATED_MODULE_AFTER_VOTE["priorityExitShareThreshold"], + CURATED_MODULE_AFTER_VOTE["maxDepositsPerBlock"], + CURATED_MODULE_AFTER_VOTE["minDepositBlockDistance"], + ), + StakingModuleItem( + SDVT_MODULE_AFTER_VOTE["id"], + SDVT_MODULE_AFTER_VOTE["stakingModuleFee"], + SDVT_MODULE_AFTER_VOTE["targetShare"], + SDVT_MODULE_AFTER_VOTE["treasuryFee"], + SDVT_MODULE_AFTER_VOTE["priorityExitShareThreshold"], + SDVT_MODULE_AFTER_VOTE["maxDepositsPerBlock"], + SDVT_MODULE_AFTER_VOTE["minDepositBlockDistance"], + ), + ], + ) + + nor_new_app = contracts.nor_app_repo.getLatest() + assert_repo_update(nor_new_app, nor_old_app, NODE_OPERATORS_REGISTRY_IMPL, nor_uri) + validate_repo_upgrade_event(events[6], RepoUpgrade(2, nor_new_app[0])) + validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL) + validate_nor_update(events[8], NOR_VERSION) + + sdvt_new_app = contracts.simple_dvt_app_repo.getLatest() + assert_repo_update(sdvt_new_app, sdvt_old_app, SIMPLE_DVT_IMPL, sdvt_uri) + validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) + validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL) + validate_nor_update(events[11], SDVT_VERSION) + + sandbox_new_app = contracts.sandbox_repo.getLatest() + assert_repo_update(sandbox_new_app, sandbox_old_app, SANDBOX_IMPL, sandbox_uri) + validate_repo_upgrade_event(events[12], RepoUpgrade(2, sandbox_new_app[0])) + # validate_app_update_event(events[13], SANDBOX_DVT_ARAGON_APP_ID, SANDBOX_DVT_IMPL) + # validate_nor_update(events[14], SANDBOX_VERSION) + + # AO + validate_upgrade_events(events[15], ACCOUNTING_ORACLE_IMPL) + validate_ao_update(events[16], AO_VERSION, AO_CONSENSUS_VERSION) + + validate_grant_role_event( + events[17], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + ) + + validate_vebo_consensus_version_set(events[18]) + + validate_revoke_role_event( + events[19], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address + ) + + # 20 - add of staking module + + # validate_module_add(events[20], CSM_AFTER_VOTE) + validate_grant_role_event(events[21], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, contracts.agent.address) + validate_grant_role_event(events[22], RESUME_ROLE, contracts.agent.address, contracts.agent.address) + + validate_resume_event(events[23]) + validate_revoke_role_event(events[24], RESUME_ROLE, contracts.agent.address, contracts.agent.address) + validate_updateInitial_epoch(events[25]) + + check_csm() + + +def check_ossifiable_proxy_impl(proxy, expected_impl): + current_impl_address = proxy.proxy__getImplementation() + assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" + + +def check_dsm_roles_before_vote(): + new_dsm_doesnt_have_unvet_role = contracts.staking_router.hasRole( + STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module + ) + assert not new_dsm_doesnt_have_unvet_role + + old_dsm_has_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) + + assert old_dsm_has_pause_role + old_dsm_has_resume_role = contracts.staking_router.hasRole( + STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 + ) + + assert old_dsm_has_resume_role + + +def check_dsm_roles_after_vote(): + new_dsm_has_unvet_role = contracts.staking_router.hasRole( + STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module + ) + assert new_dsm_has_unvet_role + + old_dsm_doesnt_have_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) + assert not old_dsm_doesnt_have_pause_role + + old_dsm_doesnt_have_resume_role = contracts.staking_router.hasRole( + STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 + ) + assert not old_dsm_doesnt_have_resume_role + + +def check_manage_consensus_role(): + agent_has_manage_consensus_role = contracts.validators_exit_bus_oracle.hasRole( + MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address + ) + assert not agent_has_manage_consensus_role + + +def check_module_before_vote(expected_module_data: Dict): + sr_contract = Contract.from_abi("StakingContract", contracts.staking_router.address, OLD_SR_ABI) + module = sr_contract.getStakingModule(expected_module_data["id"]) + assert module["id"] == expected_module_data["id"] + assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] + assert module["treasuryFee"] == expected_module_data["treasuryFee"] + assert module["stakeShareLimit"] == expected_module_data["targetShare"] + assert "priorityExitShareThreshold" not in module + assert "maxDepositsPerBlock" not in module + assert "minDepositBlockDistance" not in module + + +def check_module_after_vote(expected_module_data: Dict): + module = contracts.staking_router.getStakingModule(expected_module_data["id"]) + assert module["id"] == expected_module_data["id"] + assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] + assert module["treasuryFee"] == expected_module_data["treasuryFee"] + assert module["stakeShareLimit"] == expected_module_data["targetShare"] + assert module["priorityExitShareThreshold"] == expected_module_data["priorityExitShareThreshold"] + assert module["maxDepositsPerBlock"] == expected_module_data["maxDepositsPerBlock"] + assert module["minDepositBlockDistance"] == expected_module_data["minDepositBlockDistance"] + + +def assert_repo_before_vote(old_app, version, contract_address, old_content_uri): + assert old_app[0][0] == version + assert old_app[2] == old_content_uri, "Content uri before vote is wrong" + assert old_app[1] == contract_address, "New address should match" + + +def assert_repo_update(new_app, old_app, contract_address, old_content_uri): + assert old_app[1] != new_app[1], "Address should change" + assert new_app[1] == contract_address, "New address should match" + assert new_app[0][0] == old_app[0][0] + 1, "Major version should increment" + assert old_app[2] == new_app[2], "Content uri should not be changed" + assert new_app[2] == old_content_uri, "Content uri should match" + + +def check_csm(): + cs = contracts.staking_router.getStakingModule(4) + + assert cs["name"] == CSM_AFTER_VOTE["name"] + assert cs["stakingModuleFee"] == CSM_AFTER_VOTE["stakingModuleFee"] + assert cs["treasuryFee"] == CSM_AFTER_VOTE["treasuryFee"] + assert cs["stakeShareLimit"] == CSM_AFTER_VOTE["targetShare"] + assert cs["priorityExitShareThreshold"] == CSM_AFTER_VOTE["priorityExitShareThreshold"] + assert cs["maxDepositsPerBlock"] == CSM_AFTER_VOTE["maxDepositsPerBlock"] + assert cs["minDepositBlockDistance"] == CSM_AFTER_VOTE["minDepositBlockDistance"] + + +# Events check + + +def validate_upgrade_events(events: EventDict, implementation: str): + _events_chain = ["LogScriptCall", "LogScriptCall", "Upgraded", "ScriptResult"] + validate_events_chain([e.name for e in events], _events_chain) + assert events.count("Upgraded") == 1 + assert events["Upgraded"]["implementation"] == implementation, "Wrong withdrawal vault proxy implementation" + + +def validate_dsm_roles_events(events: EventDict): + validate_revoke_role_event( + events[1], PAUSE_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address + ) + validate_revoke_role_event( + events[2], STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address + ) + + validate_grant_role_event( + events[3], STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module.address, contracts.agent.address + ) + + +def validate_staking_module_update(event: EventDict, module_items: List[StakingModuleItem]): + + assert len(module_items) == 2 + + _events_chain = [ + "LogScriptCall", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ContractVersionSet", + ] + + validate_events_chain([e.name for e in event], _events_chain) + + assert event.count("StakingModuleFeesSet") == 3 + assert event.count("StakingModuleShareLimitSet") == 3 + assert event.count("StakingModuleMinDepositBlockDistanceSet") == 3 + assert event.count("StakingModuleMaxDepositsPerBlockSet") == 3 + assert event.count("ContractVersionSet") == 1 + + # curated + assert event["StakingModuleShareLimitSet"][0]["stakingModuleId"] == module_items[0].id + assert event["StakingModuleShareLimitSet"][0]["stakeShareLimit"] == module_items[0].stake_share_limit + assert ( + event["StakingModuleShareLimitSet"][0]["priorityExitShareThreshold"] + == module_items[0].priority_exit_share_threshold + ) + assert event["StakingModuleFeesSet"][0]["stakingModuleId"] == module_items[0].id + assert event["StakingModuleFeesSet"][0]["stakingModuleFee"] == module_items[0].staking_module_fee + assert event["StakingModuleFeesSet"][0]["treasuryFee"] == module_items[0].treasury_fee + + assert ( + event["StakingModuleMaxDepositsPerBlockSet"][0]["maxDepositsPerBlock"] == module_items[0].max_deposits_per_block + ) + + assert ( + event["StakingModuleMinDepositBlockDistanceSet"][0]["minDepositBlockDistance"] + == module_items[0].min_deposit_block_distance + ) + + assert event["ContractVersionSet"]["version"] == SR_VERSION + + assert event["StakingModuleShareLimitSet"][1]["stakingModuleId"] == module_items[1].id + assert event["StakingModuleShareLimitSet"][1]["stakeShareLimit"] == module_items[1].stake_share_limit + assert ( + event["StakingModuleShareLimitSet"][1]["priorityExitShareThreshold"] + == module_items[1].priority_exit_share_threshold + ) + assert event["StakingModuleFeesSet"][1]["stakingModuleId"] == module_items[1].id + assert event["StakingModuleFeesSet"][1]["stakingModuleFee"] == module_items[1].staking_module_fee + assert event["StakingModuleFeesSet"][1]["treasuryFee"] == module_items[1].treasury_fee + + assert ( + event["StakingModuleMaxDepositsPerBlockSet"][1]["maxDepositsPerBlock"] == module_items[1].max_deposits_per_block + ) + + assert ( + event["StakingModuleMinDepositBlockDistanceSet"][1]["minDepositBlockDistance"] + == module_items[1].min_deposit_block_distance + ) + + +def validate_nor_update(event: EventDict, version): + _events_chain = [ + "LogScriptCall", + "ContractVersionSet", + "RewardDistributionStateChanged", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["ContractVersionSet"]["version"] == version + assert event["RewardDistributionStateChanged"]["state"] == DISTRIBUTED + + +def validate_ao_update(event: EventDict, version, ao_consensus_version): + _events_chain = [ + "LogScriptCall", + "ContractVersionSet", + "ConsensusVersionSet", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["ContractVersionSet"]["version"] == version + assert event["ConsensusVersionSet"]["version"] == ao_consensus_version + assert event["ConsensusVersionSet"]["prevVersion"] == ao_consensus_version - 1 + + +def validate_vebo_consensus_version_set(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "ConsensusVersionSet", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event["ConsensusVersionSet"]["version"] == VEBO_CONSENSUS_VERSION + + +def validate_resume_event(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "Resumed", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event.count("Resumed") == 1 + + +def validate_updateInitial_epoch(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "FrameConfigSet", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event["FrameConfigSet"]["newInitialEpoch"] == CS_ORACLE_INITIAL_EPOCH + + +def validate_module_add(event, csm): + _events_chain = [ + "LogScriptCall", + "StakingRouterETHDeposited", + "StakingModuleAdded", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ScriptResult", + ] + validate_events_chain([e.name for e in event], _events_chain) diff --git a/scripts/mainnet/vote_sr_v2_mainnet.py b/scripts/mainnet/vote_sr_v2_mainnet.py index 1699d804e..94e2c0f90 100644 --- a/scripts/mainnet/vote_sr_v2_mainnet.py +++ b/scripts/mainnet/vote_sr_v2_mainnet.py @@ -90,9 +90,9 @@ CS_ORACLE_INITIAL_EPOCH = 58050 # !!!! that is locally deployed factory address, before run set you value -NEW_TARGET_LIMIT_FACTORY = "0xA3b48c7b901fede641B596A4C10a4630052449A6" +NEW_TARGET_LIMIT_FACTORY = "0xd2983525E903Ef198d5dD0777712EB66680463bc" OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" -EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "" +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xe8c3F27D20472e4f3C546A3f73C04B54DD72871d" description = """ Proposal to support DSM 2.0 and CSM Module @@ -357,13 +357,13 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ] ), ), - # ( - # "24. Add CS settle EL stealing factory to ET", - # add_evmscript_factory( - # factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, - # permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), - # ), - # ), + ( + "26. Add CS settle EL stealing factory to ET", + add_evmscript_factory( + factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, + permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), + ), + ), ) vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) diff --git a/tests/test_vote_sr_v2_mainnet.py b/tests/test_vote_sr_v2_mainnet.py index fc74cdc00..b7433fe16 100644 --- a/tests/test_vote_sr_v2_mainnet.py +++ b/tests/test_vote_sr_v2_mainnet.py @@ -173,8 +173,9 @@ class StakingModuleItem(NamedTuple): } ] +NEW_TARGET_LIMIT_FACTORY = "0xd2983525E903Ef198d5dD0777712EB66680463bc" OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" -NEW_TARGET_LIMIT_FACTORY = "0xA3b48c7b901fede641B596A4C10a4630052449A6" +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xe8c3F27D20472e4f3C546A3f73C04B54DD72871d" def test_vote( @@ -259,7 +260,7 @@ def test_vote( # events = group_voting_events(vote_tx) events = group_voting_events_from_receipt(vote_tx) - assert len(events) == 25 + assert len(events) == 26 validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) @@ -350,6 +351,15 @@ def test_vote( validate_revoke_role_event(events[23], RESUME_ROLE, contracts.agent.address, contracts.agent.address) validate_updateInitial_epoch(events[24]) + validate_evmscript_factory_added_event( + events[25], + EVMScriptFactoryAdded( + factory_addr=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, + permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), + ), + ["LogScriptCall", "EVMScriptFactoryAdded", "ScriptResult", "ExecuteVote"], + ) + def check_ossifiable_proxy_impl(proxy, expected_impl): current_impl_address = proxy.proxy__getImplementation() diff --git a/utils/test/event_validators/easy_track.py b/utils/test/event_validators/easy_track.py index 969a423bd..41d2d4dd0 100644 --- a/utils/test/event_validators/easy_track.py +++ b/utils/test/event_validators/easy_track.py @@ -9,9 +9,9 @@ class EVMScriptFactoryAdded(NamedTuple): permissions: str -def validate_evmscript_factory_added_event(event: EventDict, p: EVMScriptFactoryAdded): - _events_chain = ["LogScriptCall", "EVMScriptFactoryAdded"] - +def validate_evmscript_factory_added_event( + event: EventDict, p: EVMScriptFactoryAdded, _events_chain=["LogScriptCall", "EVMScriptFactoryAdded"] +): validate_events_chain([e.name for e in event], _events_chain) assert event.count("EVMScriptFactoryAdded") == 1 From 93fa9ae840cab6580a017ff321461f80e03ab451 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 5 Jul 2024 01:51:15 +0400 Subject: [PATCH 076/220] fix: revert configs --- configs/config_mainnet copy.py | 312 --------------------------------- configs/config_mainnet.py | 19 +- 2 files changed, 7 insertions(+), 324 deletions(-) delete mode 100644 configs/config_mainnet copy.py diff --git a/configs/config_mainnet copy.py b/configs/config_mainnet copy.py deleted file mode 100644 index 0eb5c93b3..000000000 --- a/configs/config_mainnet copy.py +++ /dev/null @@ -1,312 +0,0 @@ -# Ethereum Chain parameters -CHAIN_NETWORK_NAME = "mainnet" -CHAIN_SLOTS_PER_EPOCH = 32 -CHAIN_SECONDS_PER_SLOT = 12 -CHAIN_GENESIS_TIME = 1606824023 -CHAIN_DEPOSIT_CONTRACT = "0x00000000219ab540356cBB839Cbe05303d7705Fa" - -# DAO -ARAGON_KERNEL = "0xb8FFC3Cd6e7Cf5a098A1c92F48009765B24088Dc" -LDO_TOKEN = "0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32" -ARAGON_KERNEL_IMPL = "0x2b33CF282f867A7FF693A66e11B0FcC5552e4425" - -# Standard (or forked) Aragon apps -ACL = "0x9895F0F17cc1d1891b6f18ee0b483B6f221b37Bb" -AGENT = "0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c" -FINANCE = "0xB9E5CBB9CA5b0d659238807E84D0176930753d86" -VOTING = "0x2e59A20f205bB85a89C53f1936454680651E618e" -TOKEN_MANAGER = "0xf73a1260d222f447210581DDf212D915c09a3249" -ACL_IMPL = "0x9f3b9198911054B122fDb865f8A5Ac516201c339" -VOTING_IMPL = "0x72fb5253AD16307B9E773d2A78CaC58E309d5Ba4" - -# Our custom Aragon apps -LIDO = "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84" -LEGACY_ORACLE = "0x442af784A788A5bd6F42A01Ebe9F287a871243fb" -NODE_OPERATORS_REGISTRY = "0x55032650b14df07b85bF18A3a3eC8E0Af2e028d5" -SIMPLE_DVT = "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" - -LIDO_IMPL_V1 = "0x47EbaB13B806773ec2A2d16873e2dF770D130b50" -LEGACY_ORACLE_IMPL_V1 = "0x1430194905301504e8830ce4B0b0df7187E84AbD" -NODE_OPERATORS_REGISTRY_IMPL_V1 = "0x5d39ABaa161e622B99D45616afC8B837E9F19a25" # was used in archived tests - -# Aragon APM Repos -REPO_APP_ID = "0xbe49cbb8894efb45c933fd09dc87bdd94909553a9e1f511d7fc10f3dad1564f2" -APM_REGISTRY = "0x0cb113890b04B49455DfE06554e2D784598A29C9" -VOTING_REPO = "0x4Ee3118E3858E8D7164A634825BfE0F73d99C792" -LIDO_REPO = "0xF5Dc67E54FC96F993CD06073f71ca732C1E654B1" -NODE_OPERATORS_REGISTRY_REPO = "0x0D97E876ad14DB2b183CFeEB8aa1A5C788eB1831" -LEGACY_ORACLE_REPO = "0xF9339DE629973c60c4d2b76749c81E6F40960E3A" - -## LIDO_ARAGON_REPO_IMPL is common for Lido, NodeOperatorsRegistry, Oracle aragon apps -ARAGON_COMMON_REPO_IMPL = "0xa8A358E9bbB9fF60D4B89CBE5b2FE88f98b51B9D" - -# Other Aragon contracts -## For LIDO_EVM_SCRIPT_REGISTRY see Aragon Agent 0x853cc0D5917f49B57B8e9F89e491F5E18919093A -ARAGON_EVMSCRIPT_REGISTRY = "0x853cc0D5917f49B57B8e9F89e491F5E18919093A" -## See getEVMScriptExecutor(0x00000001) of any Aragon App or callsScript of LIDO_EASYTRACK_EVMSCRIPTEXECUTOR -ARAGON_CALLS_SCRIPT = "0x5cEb19e1890f677c3676d5ecDF7c501eBA01A054" - -# Other (non-aragon) protocol contracts -WSTETH_TOKEN = "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0" - -EXECUTION_LAYER_REWARDS_VAULT = "0x388C818CA8B9251b393131C08a736A67ccB19297" - -DEPOSIT_SECURITY_MODULE_V1 = "0x710B3303fB508a84F10793c1106e32bE873C24cd" -WITHDRAWAL_VAULT = "0xB9D7934878B5FB9610B3fE8A5e441e8fad7E293f" - -# EasyTracks -EASYTRACK = "0xF0211b7660680B49De1A7E9f25C65660F0a13Fea" - -EASYTRACK_EVMSCRIPT_EXECUTOR = "0xFE5986E06210aC1eCC1aDCafc0cc7f8D63B3F977" -EASYTRACK_INCREASE_NOP_STAKING_LIMIT_FACTORY = "0xFeBd8FAC16De88206d4b18764e826AF38546AfE0" -EASYTRACK_SIMPLE_DVT_TRUSTED_CALLER = "0x08637515E85A4633E23dfc7861e2A9f53af640f7" -EASYTRACK_SIMPLE_DVT_ADD_NODE_OPERATORS_FACTORY = "0xcAa3AF7460E83E665EEFeC73a7a542E5005C9639" -EASYTRACK_SIMPLE_DVT_ACTIVATE_NODE_OPERATORS_FACTORY = "0xCBb418F6f9BFd3525CE6aADe8F74ECFEfe2DB5C8" -EASYTRACK_SIMPLE_DVT_DEACTIVATE_NODE_OPERATORS_FACTORY = "0x8B82C1546D47330335a48406cc3a50Da732672E7" -EASYTRACK_SIMPLE_DVT_SET_VETTED_VALIDATORS_LIMITS_FACTORY = "0xD75778b855886Fc5e1eA7D6bFADA9EB68b35C19D" -EASYTRACK_SIMPLE_DVT_SET_NODE_OPERATOR_NAMES_FACTORY = "0x7d509BFF310d9460b1F613e4e40d342201a83Ae4" -EASYTRACK_SIMPLE_DVT_SET_NODE_OPERATOR_REWARD_ADDRESSES_FACTORY = "0x589e298964b9181D9938B84bB034C3BB9024E2C0" -EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" -EASYTRACK_SIMPLE_DVT_CHANGE_NODE_OPERATOR_MANAGERS_FACTORY = "0xE31A0599A6772BCf9b2bFc9e25cf941e793c9a7D" - -# Multisigs -FINANCE_MULTISIG = "0x48F300bD3C52c7dA6aAbDE4B683dEB27d38B9ABb" - -# Other -INSURANCE_FUND = "0x8B3f33234ABD88493c0Cd28De33D583B70beDe35" -RELAY_ALLOWED_LIST = "0xF95f069F9AD107938F6ba802a3da87892298610E" -CURVE_REWARDS_MANAGER = "0x753D5167C31fBEB5b49624314d74A957Eb271709" -BALANCER_REWARDS_MANAGER = "0x1dD909cDdF3dbe61aC08112dC0Fdf2Ab949f79D8" - -# Auxiliary addresses -LDO_HOLDER_ADDRESS_FOR_TESTS = "0x820fb25352bb0c5e03e07afc1d86252ffd2f0a18" -LDO_VOTE_EXECUTORS_FOR_TESTS = [ - "0x3e40d73eb977dc6a537af587d48316fee66e9c8c", - "0xb8d83908aab38a159f3da47a59d84db8e1838712", - "0xa2dfc431297aee387c05beef507e5335e684fbcd", -] -# General network addresses -DAI_TOKEN = "0x6b175474e89094c44da98b954eedeac495271d0f" -USDT_TOKEN = "0xdac17f958d2ee523a2206206994597c13d831ec7" -USDC_TOKEN = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" -WETH_TOKEN = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - -# -# Lido V2 upgrade entries -# Grouped the same as in docs -# - -# LidoLocator -LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x26Df0Ea798971A97Ae121514B32999DfDb220e1f" # set address here after SR V2 deploy - -# Other upgrade addresses -LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" -DUMMY_IMPL = "0x6F6541C2203196fEeDd14CD2C09550dA1CbEDa31" -INITIAL_DEAD_TOKEN_HOLDER = "0x000000000000000000000000000000000000dead" -DEPLOYER_EOA_LOCATOR = "0x2A78076BF797dAC2D25c9568F79b61aFE565B88C" -DEPLOYER_EOA = "0x8Ea83AD72396f1E0cD2f8E72b1461db8Eb6aF7B5" - -# 0x01...withdrawal_vault or Lido.getWithdrawalCredentials() -WITHDRAWAL_CREDENTIALS = "0x010000000000000000000000b9d7934878b5fb9610b3fe8a5e441e8fad7e293f" - -# Lido -LIDO_IMPL = "0x17144556fd3424EDC8Fc8A4C940B2D04936d17eb" -# see Lido's proxy appId() -LIDO_ARAGON_APP_ID = "0x3ca7c3e38968823ccb4c78ea688df41356f182ae1d159e4ee608d30d68cef320" -LIDO_MAX_STAKE_LIMIT_ETH = 150_000 - -# LegacyOracle (former LidoOracle) -## address is LIDO_LEGACY_ORACLE -LEGACY_ORACLE_IMPL = "0xa29b819654cE6224A222bb5f586920105E2D7E0E" -## see LidoOracle's proxy appId() -ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" - -# NodeOperatorsRegistry aka Curated Staking Module -NODE_OPERATORS_REGISTRY_IMPL = "0xa9efDEf197130B945462163a0B852019BA529a66" # set address here after SR V2 deploy -## see NodeOperatorsRegistry's proxy appId() -NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" -NODE_OPERATORS_REGISTRY_VERSION = 3 - -CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY = 432000 -CURATED_STAKING_MODULE_TARGET_SHARE_BP = 10000 -CURATED_STAKING_MODULE_MODULE_FEE_BP = 500 -CURATED_STAKING_MODULE_TREASURY_FEE_BP = 500 -CURATED_STAKING_MODULE_ID = 1 -CURATED_STAKING_MODULE_NAME = "curated-onchain-v1" -CURATED_STAKING_MODULE_TYPE = ( - # bytes32("curated-onchain-v1") - "0x637572617465642d6f6e636861696e2d76310000000000000000000000000000" -) -CURATED_STAKING_MODULE_OPERATORS_COUNT = 39 -CURATED_STAKING_MODULE_OPERATORS_ACTIVE_COUNT = 37 - -# NodeOperatorsRegistry clone aka SimpleDVT -SIMPLE_DVT_IMPL = "0xa9efDEf197130B945462163a0B852019BA529a66" -SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" -## see SimpleDVT's proxy appId() -SIMPLE_DVT_ARAGON_APP_NAME = "simple-dvt" -SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" -SIMPLE_DVT_MODULE_STUCK_PENALTY_DELAY = 432000 -SIMPLE_DVT_MODULE_TARGET_SHARE_BP = 50 -SIMPLE_DVT_MODULE_MODULE_FEE_BP = 800 -SIMPLE_DVT_MODULE_TREASURY_FEE_BP = 200 -SIMPLE_DVT_MODULE_ID = 2 -SIMPLE_DVT_MODULE_NAME = "SimpleDVT" -SIMPLE_DVT_MODULE_TYPE = ( - # bytes32("curated-onchain-v1") - "0x637572617465642d6f6e636861696e2d76310000000000000000000000000000" -) -SIMPLE_DVT_VERSION = 3 - -# OracleDaemonConfig -ORACLE_DAEMON_CONFIG = "0xbf05A929c3D7885a6aeAd833a992dA6E5ac23b09" -NORMALIZED_CL_REWARD_PER_EPOCH = 64 -NORMALIZED_CL_REWARD_MISTAKE_RATE_BP = 1000 # 10% -REBASE_CHECK_NEAREST_EPOCH_DISTANCE = 1 -REBASE_CHECK_DISTANT_EPOCH_DISTANCE = 23 # 10% of AO 225 epochs frame -VALIDATOR_DELAYED_TIMEOUT_IN_SLOTS = 7200 # 1 day -VALIDATOR_DELINQUENT_TIMEOUT_IN_SLOTS = 28800 # 4 days -NODE_OPERATOR_NETWORK_PENETRATION_THRESHOLD_BP = 100 # 1% -PREDICTION_DURATION_IN_SLOTS = 50400 -FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT = 1350 # 6 days - -# OracleReportSanityChecker -ORACLE_REPORT_SANITY_CHECKER = "0x9305c1Dbfe22c12c66339184C0025d7006f0f1cC" -APPEARED_VALIDATORS_PER_DAY_LIMIT = 43200 -EXITED_VALIDATORS_PER_DAY_LIMIT = 9000 -ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT = 500 # 5% -ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% -SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT = 50 # 0.5% -MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT = 600 -MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT = 8 -MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT = 62 -REQUEST_TIMESTAMP_MARGIN = 7680 # 2 hours rounded to epoch length -MAX_POSITIVE_TOKEN_REBASE = 750000 - -# Burner -BURNER = "0xD15a672319Cf0352560eE76d9e89eAB0889046D3" -TOTAL_NON_COVER_SHARES_BURNT = 32145684728326685744 -TOTAL_COVER_SHARES_BURNT = 0 - -# DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0x06786bCbc114bbfa670E30A1AC35dFd1310Be82f" # set address here after SR V2 deploy -DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact -DSM_MAX_OPERATORS_PER_UNVETTING = 200 -DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS = 6646 -## Migrated from LIDO_DEPOSIT_SECURITY_MODULE_V1 -DSM_GUARDIANS = [ - "0x5fd0dDbC3351d009eb3f88DE7Cd081a614C519F1", - "0x7912Fa976BcDe9c2cf728e213e892AD7588E6AaF", - "0x14D5d5B71E048d2D75a39FfC5B407e3a3AB6F314", - "0xf82D88217C249297C6037BA77CE34b3d8a90ab43", - "0xa56b128Ea2Ea237052b0fA2a96a387C0E43157d8", - "0xd4EF84b638B334699bcf5AF4B0410B8CCD71943f", -] -DSM_GUARDIAN_QUORUM = 4 - -# AccountingOracle -# and its corresponding HashConsensus -ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0xD61210E756f7D71Cc4F74abF0747D65Ea9d7525b" # set address here after SR V2 deploy -HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" -AO_EPOCHS_PER_FRAME = 225 -AO_FAST_LANE_LENGTH_SLOTS = 100 -AO_CONSENSUS_VERSION = 2 - -# ValidatorsExitBusOracle -VALIDATORS_EXIT_BUS_ORACLE = "0x0De4Ea0184c2ad0BacA7183356Aea5B8d5Bf5c6e" -VALIDATORS_EXIT_BUS_ORACLE_IMPL = "0xA89Ea51FddE660f67d1850e03C9c9862d33Bc42c" -HASH_CONSENSUS_FOR_VEBO = "0x7FaDB6358950c5fAA66Cb5EB8eE5147De3df355a" -VEBO_EPOCHS_PER_FRAME = 75 -VEBO_FAST_LANE_LENGTH_SLOTS = 100 -VEBO_CONSENSUS_VERSION = 2 - - -# AccountingOracle and ValidatorsExitBusOracle -## Migrated from LidoOracle (LegacyOracle) -ORACLE_QUORUM = 5 -ORACLE_COMMITTEE = ( - "0x140Bd8FbDc884f48dA7cb1c09bE8A2fAdfea776E", - # "0x1d0813bf088BE3047d827D98524fBf779Bc25F00", Excluded from members in vote 2024/01/16 - "0xA7410857ABbf75043d61ea54e07D57A6EB6EF186", - "0x404335BcE530400a5814375E7Ec1FB55fAff3eA2", - "0x946D3b081ed19173dC83Cd974fC69e1e760B7d78", - "0x007DE4a5F7bc37E2F26c0cb2E8A95006EE9B89b5", - "0xEC4BfbAF681eb505B94E4a7849877DC6c600Ca3A", - "0x61c91ECd902EB56e314bB2D5c5C07785444Ea1c8", - "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d", - "0xc79F702202E3A6B0B6310B537E786B9ACAA19BAf", # Added into members in vote 2024/01/16 -) - -# WithdrawalQueueERC721 -WITHDRAWAL_QUEUE = "0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1" -WITHDRAWAL_QUEUE_IMPL = "0xE42C659Dc09109566720EA8b2De186c2Be7D94D9" -WQ_ERC721_TOKEN_NAME = "Lido: stETH Withdrawal NFT" -WQ_ERC721_TOKEN_SYMBOL = "unstETH" -WQ_ERC721_TOKEN_BASE_URI = "https://wq-api.lido.fi/v1/nft" - -# WithdrawalsVault -WITHDRAWAL_VAULT_IMPL_V1 = "0xe681faB8851484B57F32143FD78548f25fD59980" -WITHDRAWAL_VAULT_IMPL = "0xCC52f17756C04bBa7E377716d7062fC36D7f69Fd" - -# EIP712StETH -EIP712_STETH = "0x8F73e4C2A6D852bb4ab2A45E6a9CF5715b3228B7" - -# StakingRouter -STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" - -STAKING_ROUTER_IMPL = "0x49AeF2C4005Bf572665b09014A563B5b9E46Df21" # set address here after SR V2 deploy -STAKING_ROUTER_VERSION = 2 - - -# Not a precise but still some estimation of the fees. Assume here that both modules are filled -# SR_MODULES_FEE = curated_module_fee * (100% - sdvt_module_share) + sdvt_module_fee * sdvt_module_share - -SR_MODULES_FEE_BP = ( - CURATED_STAKING_MODULE_MODULE_FEE_BP * (100_00 - SIMPLE_DVT_MODULE_TARGET_SHARE_BP) - + SIMPLE_DVT_MODULE_MODULE_FEE_BP * SIMPLE_DVT_MODULE_TARGET_SHARE_BP -) // 100_00 - -SR_TREASURY_FEE_BP = ( - CURATED_STAKING_MODULE_TREASURY_FEE_BP * (100_00 - SIMPLE_DVT_MODULE_TARGET_SHARE_BP) - + SIMPLE_DVT_MODULE_TREASURY_FEE_BP * SIMPLE_DVT_MODULE_TARGET_SHARE_BP -) // 100_00 - -SR_MODULES_FEE_E20 = ( - CURATED_STAKING_MODULE_MODULE_FEE_BP * (100_00 - SIMPLE_DVT_MODULE_TARGET_SHARE_BP) - + SIMPLE_DVT_MODULE_MODULE_FEE_BP * SIMPLE_DVT_MODULE_TARGET_SHARE_BP -) * 10**12 - -# same as for SR_MODULES_FEE_E20 -SR_TREASURY_FEE_E20 = ( - CURATED_STAKING_MODULE_TREASURY_FEE_BP * (100_00 - SIMPLE_DVT_MODULE_TARGET_SHARE_BP) - + SIMPLE_DVT_MODULE_TREASURY_FEE_BP * SIMPLE_DVT_MODULE_TARGET_SHARE_BP -) * 10**12 - -SR_BASE_PRECISION_E20 = 100 * 10**18 - -# GateSeal -GATE_SEAL_FACTORY = "0x6C82877cAC5a7A739f16Ca0A89c0A328B8764A24" -GATE_SEAL = "0x79243345eDbe01A7E42EDfF5900156700d22611c" -GATE_SEAL_PAUSE_DURATION = 518400 # 6 days -GATE_SEAL_EXPIRY_TIMESTAMP = 1743465600 # 2025-05-01 00:00GMT -GATE_SEAL_COMMITTEE = "0x8772E3a2D86B9347A2688f9bc1808A6d8917760C" - -# Aragon Permissions test -ACL_DEPLOY_BLOCK_NUMBER = 11473216 - -# Obsolete (can be removed after V2 upgrade) -SELF_OWNED_STETH_BURNER = "0xB280E33812c0B09353180e92e27b8AD399B07f26" - -# Anchor -ANCHOR_VAULT_PROXY = "0xA2F987A546D4CD1c607Ee8141276876C26b72Bdf" - -# 0xSplits -SPLIT_MAIN = "0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE" - -# Rewards Wrapper (aka ObolLidoSplit) -OBOL_LIDO_SPLIT_FACTORY = "0xA9d94139A310150Ca1163b5E23f3E1dbb7D9E2A6" -OBOL_LIDO_SPLIT_IMPL = "0x2fB59065F049e0D0E3180C6312FA0FeB5Bbf0FE3" - -SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index c28d57858..f980fe23d 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -98,7 +98,7 @@ # LidoLocator LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x26Df0Ea798971A97Ae121514B32999DfDb220e1f" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" # set address here after SR V2 deploy # Other upgrade addresses LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" @@ -123,7 +123,7 @@ ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" # NodeOperatorsRegistry aka Curated Staking Module -NODE_OPERATORS_REGISTRY_IMPL = "0xa9efDEf197130B945462163a0B852019BA529a66" # set address here after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" # set address here after SR V2 deploy ## see NodeOperatorsRegistry's proxy appId() NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" NODE_OPERATORS_REGISTRY_VERSION = 3 @@ -142,7 +142,7 @@ CURATED_STAKING_MODULE_OPERATORS_ACTIVE_COUNT = 37 # NodeOperatorsRegistry clone aka SimpleDVT -SIMPLE_DVT_IMPL = "0xa9efDEf197130B945462163a0B852019BA529a66" +SIMPLE_DVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" ## see SimpleDVT's proxy appId() SIMPLE_DVT_ARAGON_APP_NAME = "simple-dvt" @@ -190,7 +190,7 @@ TOTAL_COVER_SHARES_BURNT = 0 # DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0x06786bCbc114bbfa670E30A1AC35dFd1310Be82f" # set address here after SR V2 deploy +DEPOSIT_SECURITY_MODULE = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact DSM_MAX_OPERATORS_PER_UNVETTING = 200 DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS = 6646 @@ -208,7 +208,7 @@ # AccountingOracle # and its corresponding HashConsensus ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0xD61210E756f7D71Cc4F74abF0747D65Ea9d7525b" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" # set address here after SR V2 deploy HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 @@ -256,8 +256,8 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" -STAKING_ROUTER_IMPL = "0x49AeF2C4005Bf572665b09014A563B5b9E46Df21" # set address here after SR V2 deploy -STAKING_ROUTER_VERSION = 2 +STAKING_ROUTER_IMPL = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" # set address here after SR V2 deploy +STAKING_ROUTER_VERSION = 2 # do we need set this value now ? # Not a precise but still some estimation of the fees. Assume here that both modules are filled @@ -310,8 +310,3 @@ OBOL_LIDO_SPLIT_IMPL = "0x2fB59065F049e0D0E3180C6312FA0FeB5Bbf0FE3" SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" - - -CSM = "0xAAF0F531b7947e8492f21862471d61d5305f7538" -CS_ACCOUNTING_ADDRESS = "0x81f4f47aa3bBd154171C877b4d70F6C9EeCAb216" -CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xe4a4B3Bc2787aA913e5b4bbce907e8b213250BDe" From febe14cf22888412465b18535071d22e83342c2b Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 8 Jul 2024 12:43:55 +0200 Subject: [PATCH 077/220] feat: restore legacy updateTargetValidatorsLimits method --- interfaces/NodeOperatorsRegistry.json | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/interfaces/NodeOperatorsRegistry.json b/interfaces/NodeOperatorsRegistry.json index bbff81661..4e15f855d 100644 --- a/interfaces/NodeOperatorsRegistry.json +++ b/interfaces/NodeOperatorsRegistry.json @@ -884,6 +884,28 @@ "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_isTargetLimitActive", + "type": "bool" + }, + { + "name": "_targetLimit", + "type": "uint256" + } + ], + "name": "updateTargetValidatorsLimits", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ From a4f6571acfb371bb7c1077dedb308b36a0604313 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 5 Jul 2024 16:41:18 +0400 Subject: [PATCH 078/220] fix: read constants from vote file --- scripts/mainnet/vote_sr_v2_mainnet.py | 60 +++++++++---- tests/test_vote_sr_v2_mainnet.py | 121 ++++++++++++++------------ 2 files changed, 108 insertions(+), 73 deletions(-) diff --git a/scripts/mainnet/vote_sr_v2_mainnet.py b/scripts/mainnet/vote_sr_v2_mainnet.py index 94e2c0f90..219e53821 100644 --- a/scripts/mainnet/vote_sr_v2_mainnet.py +++ b/scripts/mainnet/vote_sr_v2_mainnet.py @@ -22,13 +22,13 @@ CSM -18. Add staking module -19. Grant request burn role to CSAccounting contract -20. Grant resume role to agent -21. Resume staking module -22. Revoke resume role from agent -23. Update initial epoch -24. Add CS settle EL stealing factory to ET +20. Add staking module +21. Grant request burn role to CSAccounting contract +22. Grant resume role to agent +23. Resume staking module +24. Revoke resume role from agent +25. Update initial epoch +26. Add CS settle EL stealing factory to ET """ import time @@ -53,7 +53,6 @@ ACCOUNTING_ORACLE_IMPL, NODE_OPERATORS_REGISTRY_IMPL, CS_ACCOUNTING_ADDRESS, - EASYTRACK, ) from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description from utils.repo import ( @@ -68,19 +67,47 @@ from brownie.network.transaction import TransactionReceipt from utils.agent import agent_forward - # SR +## Easy track +OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" +# !!!! that is locally deployed factory address, before run set contract address here +NEW_TARGET_LIMIT_FACTORY = "0x00B0517de6b2b09aBD3a7B69d66D85eFdb2c7d94" + +## SR PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000] MAX_DEPOSITS_PER_BLOCK = [50, 50] MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25] -NOR_VERSION = ["5", "0", "0"] -SDVT_VERSION = ["2", "0", "0"] + +## Curated module +nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" +CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 +CURATED_MAX_DEPOSITS_PER_BLOCK = 50 +CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 +NOR_VERSION_REPO = ["5", "0", "0"] + +### RewardDistributionState +DISTRIBUTED = 2 + +## SDVT module +sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" +SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 +SDVT_MAX_DEPOSITS_PER_BLOCK = 50 +SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 +SDVT_VERSION_REPO = ["2", "0", "0"] + +## Accounting oracle AO_CONSENSUS_VERSION = 2 +## Vebo VEBO_CONSENSUS_VERSION = 2 # CSM -CS_MODULE_NAME = "CommunityStaking" +## Easy track +# !!!! that is locally deployed factory address, before run set contract address here +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xd2983525E903Ef198d5dD0777712EB66680463bc" + +## Parameters +CS_MODULE_NAME = "Community Staking" CS_STAKE_SHARE_LIMIT = 2000 CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 CS_STAKING_MODULE_FEE = 800 @@ -89,11 +116,6 @@ CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 CS_ORACLE_INITIAL_EPOCH = 58050 -# !!!! that is locally deployed factory address, before run set you value -NEW_TARGET_LIMIT_FACTORY = "0xd2983525E903Ef198d5dD0777712EB66680463bc" -OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" -EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xe8c3F27D20472e4f3C546A3f73C04B54DD72871d" - description = """ Proposal to support DSM 2.0 and CSM Module """ @@ -213,7 +235,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ( "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", - add_implementation_to_nor_app_repo(NOR_VERSION, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), + add_implementation_to_nor_app_repo(NOR_VERSION_REPO, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), ), ( "8. Update `NodeOperatorsRegistry` implementation", @@ -225,7 +247,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ( "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", - add_implementation_to_sdvt_app_repo(SDVT_VERSION, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), + add_implementation_to_sdvt_app_repo(SDVT_VERSION_REPO, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), ), ( "11. Update `SimpleDVT` implementation", diff --git a/tests/test_vote_sr_v2_mainnet.py b/tests/test_vote_sr_v2_mainnet.py index b7433fe16..9b03b46cf 100644 --- a/tests/test_vote_sr_v2_mainnet.py +++ b/tests/test_vote_sr_v2_mainnet.py @@ -14,7 +14,35 @@ CS_ACCOUNTING_ADDRESS, CSM, ) -from scripts.mainnet.vote_sr_v2_mainnet import start_vote +from scripts.mainnet.vote_sr_v2_mainnet import ( + start_vote, + # oracles + AO_CONSENSUS_VERSION, + VEBO_CONSENSUS_VERSION, + # nor + nor_uri, + CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, + CURATED_MAX_DEPOSITS_PER_BLOCK, + CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, + # sdvt + sdvt_uri, + SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS, + SDVT_MAX_DEPOSITS_PER_BLOCK, + SDVT_MIN_DEPOSIT_BLOCK_DISTANCES, + ## easy track + OLD_TARGET_LIMIT__FACTORY, + NEW_TARGET_LIMIT_FACTORY, + # CSM + CS_MODULE_NAME, + CS_STAKE_SHARE_LIMIT, + CS_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_STAKING_MODULE_FEE, + CS_TREASURY_FEE, + CS_MAX_DEPOSITS_PER_BLOCK, + CS_MIN_DEPOSIT_BLOCK_DISTANCE, + CS_ORACLE_INITIAL_EPOCH, + EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, +) from utils.config import ( contracts, LDO_HOLDER_ADDRESS_FOR_TESTS, @@ -33,54 +61,46 @@ ) from utils.easy_track import create_permissions - -class StakingModuleItem(NamedTuple): - id: int - staking_module_address: str - name: str - staking_module_fee: int - stake_share_limit: int - treasury_fee: int - priority_exit_share_threshold: int - max_deposits_per_block: int - min_deposit_block_distance: int - - -# CSM roles -RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" -REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" - -# SR roles -STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" -PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" -STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" -MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" +# Impl addresses before vote OLD_LOCATOR_IMPL_ADDRESS = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" OLD_SR_IMPL_ADDRESS = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" OLD_NOR_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" OLD_SDVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" OLD_ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" -CURATED_MODULE_ID = 1 -SIMPLE_DVT_MODULE_ID = 2 -AO_CONSENSUS_VERSION = 2 -VEBO_CONSENSUS_VERSION = 2 +# NOR +### RewardDistributionState +DISTRIBUTED = 2 + +## Contract versions SR_VERSION = 2 NOR_VERSION = 3 -DISTRIBUTED = 2 SDVT_VERSION = 3 AO_VERSION = 2 -# new added fields -CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 -CURATED_MAX_DEPOSITS_PER_BLOCK = 50 -CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 -SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 -SDVT_MAX_DEPOSITS_PER_BLOCK = 50 -SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 +# Roles +## SR +STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" +PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" +STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" +MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" + +## CSM +RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" +REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" + + +class StakingModuleItem(NamedTuple): + id: int + staking_module_address: str + name: str + staking_module_fee: int + stake_share_limit: int + treasury_fee: int + priority_exit_share_threshold: int + max_deposits_per_block: int + min_deposit_block_distance: int -nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" -sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" CURATED_MODULE_BEFORE_VOTE = { "id": 1, @@ -124,15 +144,6 @@ class StakingModuleItem(NamedTuple): } ) -CS_MODULE_NAME = "CommunityStaking" -CS_STAKE_SHARE_LIMIT = 2000 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 -CS_STAKING_MODULE_FEE = 800 -CS_TREASURY_FEE = 200 -CS_MAX_DEPOSITS_PER_BLOCK = 30 -CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 58050 - CSM_AFTER_VOTE = { "id": 3, "name": CS_MODULE_NAME, @@ -145,7 +156,7 @@ class StakingModuleItem(NamedTuple): "minDepositBlockDistance": CS_MIN_DEPOSIT_BLOCK_DISTANCE, } -OLD_SR_ABI = bi = [ +OLD_SR_ABI = [ { "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], "name": "getStakingModule", @@ -173,10 +184,6 @@ class StakingModuleItem(NamedTuple): } ] -NEW_TARGET_LIMIT_FACTORY = "0xd2983525E903Ef198d5dD0777712EB66680463bc" -OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" -EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xe8c3F27D20472e4f3C546A3f73C04B54DD72871d" - def test_vote( helpers, @@ -212,7 +219,7 @@ def test_vote( assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, sdvt_uri) # AO check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) - # no prermission to manage consensus version on agent + # no permission to manage consensus version on agent check_manage_consensus_role() # VEBO consensus version @@ -457,11 +464,17 @@ def validate_dsm_roles_events(events: EventDict): events[1], PAUSE_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address ) validate_revoke_role_event( - events[2], STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address + events[2], + STAKING_MODULE_RESUME_ROLE, + contracts.deposit_security_module_v2.address, + contracts.agent.address, ) validate_grant_role_event( - events[3], STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module.address, contracts.agent.address + events[3], + STAKING_MODULE_UNVETTING_ROLE, + contracts.deposit_security_module.address, + contracts.agent.address, ) From 17a7b96d1c85e99c240805569b963ff793355c22 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 10 Jul 2024 20:42:24 +0200 Subject: [PATCH 079/220] test: fixes after negative rebase merge --- configs/config_mainnet.py | 4 +- interfaces/OracleReportSanityChecker.json | 377 ++++++++++++++---- .../test_oracle_report_sanity_checker.py | 10 +- tests/regression/test_permissions.py | 3 +- tests/regression/test_sanity_checks.py | 24 +- utils/test/oracle_report_helpers.py | 2 +- 6 files changed, 319 insertions(+), 101 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index f980fe23d..05b3e69c1 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -175,7 +175,6 @@ ORACLE_REPORT_SANITY_CHECKER = "0x9305c1Dbfe22c12c66339184C0025d7006f0f1cC" APPEARED_VALIDATORS_PER_DAY_LIMIT = 43200 EXITED_VALIDATORS_PER_DAY_LIMIT = 9000 -ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT = 500 # 5% ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT = 50 # 0.5% MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT = 600 @@ -183,6 +182,9 @@ MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT = 62 REQUEST_TIMESTAMP_MARGIN = 7680 # 2 hours rounded to epoch length MAX_POSITIVE_TOKEN_REBASE = 750000 +INITIAL_SLASHING_AMOUNT_PWEI = 1000 +INACTIVITY_PENALTIES_AMOUNT_PWEI = 101 +CL_BALANCE_ORACLES_ERROR_UPPER_BP_LIMIT = 74 # Burner BURNER = "0xD15a672319Cf0352560eE76d9e89eAB0889046D3" diff --git a/interfaces/OracleReportSanityChecker.json b/interfaces/OracleReportSanityChecker.json index 6c50e9878..b6ec86fbe 100644 --- a/interfaces/OracleReportSanityChecker.json +++ b/interfaces/OracleReportSanityChecker.json @@ -20,7 +20,7 @@ }, { "internalType": "uint256", - "name": "oneOffCLBalanceDecreaseBPLimit", + "name": "appearedValidatorsPerDayLimit", "type": "uint256" }, { @@ -60,74 +60,22 @@ }, { "internalType": "uint256", - "name": "appearedValidatorsPerDayLimit", + "name": "initialSlashingAmountPWei", "type": "uint256" - } - ], - "internalType": "struct LimitsList", - "name": "_limitsList", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address[]", - "name": "allLimitsManagers", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "exitedValidatorsPerDayLimitManagers", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "appearedValidatorsPerDayLimitManagers", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "oneOffCLBalanceDecreaseLimitManagers", - "type": "address[]" }, { - "internalType": "address[]", - "name": "annualBalanceIncreaseLimitManagers", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "shareRateDeviationLimitManagers", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "maxValidatorExitRequestsPerReportManagers", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "maxAccountingExtraDataListItemsCountManagers", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "maxNodeOperatorsPerExtraDataItemCountManagers", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "requestTimestampMarginManagers", - "type": "address[]" + "internalType": "uint256", + "name": "inactivityPenaltiesAmountPWei", + "type": "uint256" }, { - "internalType": "address[]", - "name": "maxPositiveTokenRebaseManagers", - "type": "address[]" + "internalType": "uint256", + "name": "clBalanceOraclesErrorUpperBPLimit", + "type": "uint256" } ], - "internalType": "struct OracleReportSanityChecker.ManagersRoster", - "name": "_managersRoster", + "internalType": "struct LimitsList", + "name": "_limitsList", "type": "tuple" } ], @@ -144,6 +92,11 @@ "name": "AdminCannotBeZero", "type": "error" }, + { + "inputs": [], + "name": "CalledNotFromLido", + "type": "error" + }, { "inputs": [ { @@ -175,7 +128,12 @@ "inputs": [ { "internalType": "uint256", - "name": "oneOffCLBalanceDecreaseBP", + "name": "negativeCLRebaseSum", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxNegativeCLRebaseSum", "type": "uint256" } ], @@ -208,7 +166,7 @@ "inputs": [ { "internalType": "uint256", - "name": "exitedValudatorsLimit", + "name": "exitedValidatorsLimit", "type": "uint256" } ], @@ -312,6 +270,48 @@ "name": "MaxAccountingExtraDataItemsCountExceeded", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reportedValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "provedValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limitBP", + "type": "uint256" + } + ], + "name": "NegativeRebaseFailedCLBalanceMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "NegativeRebaseFailedSecondOpinionReportIsNotReady", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reportedValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "provedValue", + "type": "uint256" + } + ], + "name": "NegativeRebaseFailedWithdrawalVaultBalanceMismatch", + "type": "error" + }, { "inputs": [], "name": "NegativeTotalPooledEther", @@ -369,6 +369,19 @@ "name": "AppearedValidatorsPerDayLimitSet", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "clBalanceOraclesErrorUpperBPLimit", + "type": "uint256" + } + ], + "name": "CLBalanceOraclesErrorUpperBPLimitSet", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -382,6 +395,32 @@ "name": "ExitedValidatorsPerDayLimitSet", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "inactivityPenaltiesAmountPWei", + "type": "uint256" + } + ], + "name": "InactivityPenaltiesAmountSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "initialSlashingAmountPWei", + "type": "uint256" + } + ], + "name": "InitialSlashingAmountSet", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -440,11 +479,54 @@ { "indexed": false, "internalType": "uint256", - "name": "oneOffCLBalanceDecreaseBPLimit", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clBalanceDecrease", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clBalanceMaxDecrease", "type": "uint256" } ], - "name": "OneOffCLBalanceDecreaseBPLimitSet", + "name": "NegativeCLRebaseAccepted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "clBalanceWei", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawalVaultBalance", + "type": "uint256" + } + ], + "name": "NegativeCLRebaseConfirmed", "type": "event" }, { @@ -535,6 +617,19 @@ "name": "RoleRevoked", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISecondOpinionOracle", + "name": "secondOpinionOracle", + "type": "address" + } + ], + "name": "SecondOpinionOracleChanged", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -613,6 +708,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "INITIAL_SLASHING_AND_PENALTIES_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE", @@ -667,7 +775,7 @@ }, { "inputs": [], - "name": "ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE", + "name": "REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE", "outputs": [ { "internalType": "bytes32", @@ -680,7 +788,7 @@ }, { "inputs": [], - "name": "REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE", + "name": "SECOND_OPINION_MANAGER_ROLE", "outputs": [ { "internalType": "bytes32", @@ -749,7 +857,7 @@ ], "name": "checkAccountingOracleReport", "outputs": [], - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { @@ -899,7 +1007,7 @@ }, { "internalType": "uint256", - "name": "oneOffCLBalanceDecreaseBPLimit", + "name": "appearedValidatorsPerDayLimit", "type": "uint256" }, { @@ -939,7 +1047,17 @@ }, { "internalType": "uint256", - "name": "appearedValidatorsPerDayLimit", + "name": "initialSlashingAmountPWei", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inactivityPenaltiesAmountPWei", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "clBalanceOraclesErrorUpperBPLimit", "type": "uint256" } ], @@ -951,6 +1069,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getReportDataCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1073,6 +1204,35 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "reportData", + "outputs": [ + { + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "totalExitedValidators", + "type": "uint64" + }, + { + "internalType": "uint128", + "name": "negativeCLRebaseWei", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1091,6 +1251,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "secondOpinionOracle", + "outputs": [ + { + "internalType": "contract ISecondOpinionOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1134,11 +1307,16 @@ "inputs": [ { "internalType": "uint256", - "name": "_maxAccountingExtraDataListItemsCount", + "name": "_initialSlashingAmountPWei", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_inactivityPenaltiesAmountPWei", "type": "uint256" } ], - "name": "setMaxAccountingExtraDataListItemsCount", + "name": "setInitialSlashingAndPenaltiesAmount", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1147,11 +1325,11 @@ "inputs": [ { "internalType": "uint256", - "name": "_maxValidatorExitRequestsPerReport", + "name": "_maxAccountingExtraDataListItemsCount", "type": "uint256" } ], - "name": "setMaxExitRequestsPerOracleReport", + "name": "setMaxAccountingExtraDataListItemsCount", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1160,11 +1338,11 @@ "inputs": [ { "internalType": "uint256", - "name": "_maxNodeOperatorsPerExtraDataItemCount", + "name": "_maxValidatorExitRequestsPerReport", "type": "uint256" } ], - "name": "setMaxNodeOperatorsPerExtraDataItemCount", + "name": "setMaxExitRequestsPerOracleReport", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1173,11 +1351,11 @@ "inputs": [ { "internalType": "uint256", - "name": "_maxPositiveTokenRebase", + "name": "_maxNodeOperatorsPerExtraDataItemCount", "type": "uint256" } ], - "name": "setMaxPositiveTokenRebase", + "name": "setMaxNodeOperatorsPerExtraDataItemCount", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1186,11 +1364,11 @@ "inputs": [ { "internalType": "uint256", - "name": "_oneOffCLBalanceDecreaseBPLimit", + "name": "_maxPositiveTokenRebase", "type": "uint256" } ], - "name": "setOneOffCLBalanceDecreaseBPLimit", + "name": "setMaxPositiveTokenRebase", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1206,7 +1384,7 @@ }, { "internalType": "uint256", - "name": "oneOffCLBalanceDecreaseBPLimit", + "name": "appearedValidatorsPerDayLimit", "type": "uint256" }, { @@ -1246,13 +1424,28 @@ }, { "internalType": "uint256", - "name": "appearedValidatorsPerDayLimit", + "name": "initialSlashingAmountPWei", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "inactivityPenaltiesAmountPWei", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "clBalanceOraclesErrorUpperBPLimit", "type": "uint256" } ], "internalType": "struct LimitsList", "name": "_limitsList", "type": "tuple" + }, + { + "internalType": "contract ISecondOpinionOracle", + "name": "_secondOpinionOracle", + "type": "address" } ], "name": "setOracleReportLimits", @@ -1273,6 +1466,24 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract ISecondOpinionOracle", + "name": "_secondOpinionOracle", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_clBalanceOraclesErrorUpperBPLimit", + "type": "uint256" + } + ], + "name": "setSecondOpinionOracleAndCLBalanceUpperMargin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/tests/acceptance/test_oracle_report_sanity_checker.py b/tests/acceptance/test_oracle_report_sanity_checker.py index 03ce248bc..86a50e443 100644 --- a/tests/acceptance/test_oracle_report_sanity_checker.py +++ b/tests/acceptance/test_oracle_report_sanity_checker.py @@ -6,7 +6,6 @@ ORACLE_REPORT_SANITY_CHECKER, EXITED_VALIDATORS_PER_DAY_LIMIT, APPEARED_VALIDATORS_PER_DAY_LIMIT, - ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT, ANNUAL_BALANCE_INCREASE_BP_LIMIT, SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT, MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT, @@ -14,12 +13,15 @@ MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT, REQUEST_TIMESTAMP_MARGIN, MAX_POSITIVE_TOKEN_REBASE, + INITIAL_SLASHING_AMOUNT_PWEI, + INACTIVITY_PENALTIES_AMOUNT_PWEI, + CL_BALANCE_ORACLES_ERROR_UPPER_BP_LIMIT ) # Source of truth: https://hackmd.io/pdix1r4yR46fXUqiHaNKyw?view expected_report_limits = { "exitedValidatorsPerDayLimit": EXITED_VALIDATORS_PER_DAY_LIMIT, - "oneOffCLBalanceDecreaseBPLimit": ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT, + "appearedValidatorsPerDayLimit": APPEARED_VALIDATORS_PER_DAY_LIMIT, "annualBalanceIncreaseBPLimit": ANNUAL_BALANCE_INCREASE_BP_LIMIT, "simulatedShareRateDeviationBPLimit": SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT, "maxValidatorExitRequestsPerReport": MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT, @@ -27,7 +29,9 @@ "maxNodeOperatorsPerExtraDataItemCount": MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT, "requestTimestampMargin": REQUEST_TIMESTAMP_MARGIN, "maxPositiveTokenRebase": MAX_POSITIVE_TOKEN_REBASE, - "appearedValidatorsPerDayLimit": APPEARED_VALIDATORS_PER_DAY_LIMIT, + "initialSlashingAmountPWei": INITIAL_SLASHING_AMOUNT_PWEI, + "inactivityPenaltiesAmountPWei": INACTIVITY_PENALTIES_AMOUNT_PWEI, + "clBalanceOraclesErrorUpperBPLimit": CL_BALANCE_ORACLES_ERROR_UPPER_BP_LIMIT, } diff --git a/tests/regression/test_permissions.py b/tests/regression/test_permissions.py index 037c4bd9e..d61838235 100644 --- a/tests/regression/test_permissions.py +++ b/tests/regression/test_permissions.py @@ -162,7 +162,6 @@ def protocol_permissions(): "ALL_LIMITS_MANAGER_ROLE": [], "EXITED_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE": [], "APPEARED_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE": [], - "ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE": [], "ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE": [], "SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE": [], "MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT_ROLE": [], @@ -170,6 +169,8 @@ def protocol_permissions(): "MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE": [], "REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE": [], "MAX_POSITIVE_TOKEN_REBASE_MANAGER_ROLE": [], + "SECOND_OPINION_MANAGER_ROLE": [], + "INITIAL_SLASHING_AND_PENALTIES_MANAGER_ROLE": [], }, }, DEPOSIT_SECURITY_MODULE: { diff --git a/tests/regression/test_sanity_checks.py b/tests/regression/test_sanity_checks.py index 40e42186a..263bb442b 100644 --- a/tests/regression/test_sanity_checks.py +++ b/tests/regression/test_sanity_checks.py @@ -16,7 +16,6 @@ contracts, APPEARED_VALIDATORS_PER_DAY_LIMIT, EXITED_VALIDATORS_PER_DAY_LIMIT, - ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT, ANNUAL_BALANCE_INCREASE_BP_LIMIT, MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT, MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, @@ -110,19 +109,20 @@ def test_too_much_validators_exited(): ) -def test_too_large_cl_decrease(pre_cl_balance): - # uint256 oneOffCLBalanceDecreaseBP = (MAX_BASIS_POINTS * (_preCLBalance - _unifiedPostCLBalance)) / - # _preCLBalance; +# ToDo: fix test, ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT deprecated +# def test_too_large_cl_decrease(pre_cl_balance): +# # uint256 oneOffCLBalanceDecreaseBP = (MAX_BASIS_POINTS * (_preCLBalance - _unifiedPostCLBalance)) / +# # _preCLBalance; - withdrawal_vault_balance = eth_balance(contracts.withdrawal_vault.address) - max_cl_decrease = ( - ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT * pre_cl_balance // MAX_BASIS_POINTS + withdrawal_vault_balance - ) +# withdrawal_vault_balance = eth_balance(contracts.withdrawal_vault.address) +# max_cl_decrease = ( +# ONE_OFF_CL_BALANCE_DECREASE_BP_LIMIT * pre_cl_balance // MAX_BASIS_POINTS + withdrawal_vault_balance +# ) - error_cl_decrease = max_cl_decrease + ETH(1000) - error_one_off_cl_decrease_bp = (MAX_BASIS_POINTS * (error_cl_decrease - withdrawal_vault_balance)) // pre_cl_balance - with reverts(encode_error("IncorrectCLBalanceDecrease(uint256)", [error_one_off_cl_decrease_bp])): - oracle_report(cl_diff=-error_cl_decrease, skip_withdrawals=True, silent=True) +# error_cl_decrease = max_cl_decrease + ETH(1000) +# error_one_off_cl_decrease_bp = (MAX_BASIS_POINTS * (error_cl_decrease - withdrawal_vault_balance)) // pre_cl_balance +# with reverts(encode_error("IncorrectCLBalanceDecrease(uint256)", [error_one_off_cl_decrease_bp])): +# oracle_report(cl_diff=-error_cl_decrease, skip_withdrawals=True, silent=True) def test_withdrawal_vault_report_more(): diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index 0d17045f9..a1f17fe11 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -117,7 +117,7 @@ def encode_data_from_abi(data, abi, func_name): def get_finalization_batches( share_rate: int, limited_withdrawal_vault_balance, limited_el_rewards_vault_balance ) -> list[int]: - (_, _, _, _, _, _, _, requestTimestampMargin, _, _) = contracts.oracle_report_sanity_checker.getOracleReportLimits() + (_, _, _, _, _, _, _, requestTimestampMargin, _, _, _, _) = contracts.oracle_report_sanity_checker.getOracleReportLimits() buffered_ether = contracts.lido.getBufferedEther() unfinalized_steth = contracts.withdrawal_queue.unfinalizedStETH() reserved_buffer = min(buffered_ether, unfinalized_steth) From 6b24e34bda731ce60edfde414d9d461f3d3127dc Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 22 Jul 2024 15:57:57 +0200 Subject: [PATCH 080/220] test: anvil fix submitConsensusReport test use far future timestamp as deadline instead of chain current current. --- tests/acceptance/test_accounting_oracle_negative.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/test_accounting_oracle_negative.py b/tests/acceptance/test_accounting_oracle_negative.py index 0e04d5030..a4c523f2f 100644 --- a/tests/acceptance/test_accounting_oracle_negative.py +++ b/tests/acceptance/test_accounting_oracle_negative.py @@ -44,6 +44,7 @@ def test_sender_not_allowed(accounting_oracle: Contract, oracle_version: int, st def test_submitConsensusReport(accounting_oracle: Contract, hash_consensus: Contract) -> None: last_processing_ref_slot = accounting_oracle.getLastProcessingRefSlot() + far_future = 172191406800 with reverts( encode_error( @@ -67,7 +68,7 @@ def test_submitConsensusReport(accounting_oracle: Contract, hash_consensus: Cont accounting_oracle.submitConsensusReport( NON_ZERO_HASH, last_processing_ref_slot, - chain.time(), + far_future, {"from": hash_consensus}, ) @@ -79,11 +80,12 @@ def test_submitConsensusReport(accounting_oracle: Contract, hash_consensus: Cont {"from": hash_consensus}, ) + with reverts(encode_error("HashCannotBeZero()")): accounting_oracle.submitConsensusReport( ZERO_HASH, last_processing_ref_slot + 1, - chain.time(), + far_future, {"from": hash_consensus}, ) From 6d10360e614673b4c77934f250634166e56f2fd5 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 23 Jul 2024 12:13:25 +0200 Subject: [PATCH 081/220] test: fix set address balance --- tests/conftest.py | 2 +- tests/regression/test_accounting.py | 34 +++++------------------------ utils/balance.py | 11 +++++++--- 3 files changed, 14 insertions(+), 33 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 98c60345c..7c530f5f2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -38,7 +38,7 @@ def deployer(): @pytest.fixture() def steth_holder(accounts): steth_holder = accounts.at("0x176F3DAb24a159341c0509bB36B833E7fdd0a131", force=True) - web3.provider.make_request("evm_setAccountBalance", [steth_holder.address, "0x152D02C7E14AF6800000"]) + set_balance(steth_holder.address, 100000) steth_holder.transfer(contracts.lido, ETH(10000)) return steth_holder diff --git a/tests/regression/test_accounting.py b/tests/regression/test_accounting.py index 0346494e1..324ff6e8f 100644 --- a/tests/regression/test_accounting.py +++ b/tests/regression/test_accounting.py @@ -6,7 +6,7 @@ from brownie.network.account import Account from web3 import Web3 -from utils.balance import set_balance +from utils.balance import set_balance, set_balance_in_wei from utils.evm_script import encode_error from tests.conftest import Helpers from utils.config import contracts @@ -582,13 +582,7 @@ def test_accounting_withdrawals_at_limits( withdrawals = _rebase_limit_wei(block_identifier=block_before_report) - web3.manager.request_blocking( - "evm_setAccountBalance", # type: ignore - [ - withdrawal_vault.address, - Web3.to_hex(withdrawals), - ], - ) + set_balance_in_wei(withdrawal_vault.address, withdrawals) tx, _ = oracle_report( cl_diff=0, @@ -705,13 +699,7 @@ def test_accounting_withdrawals_above_limits( withdrawals_excess = ETH(10) withdrawals = expected_withdrawals + withdrawals_excess - web3.manager.request_blocking( - "evm_setAccountBalance", # type: ignore - [ - withdrawal_vault.address, - Web3.to_hex(withdrawals), - ], - ) + set_balance_in_wei(withdrawal_vault.address, withdrawals) tx, _ = oracle_report( cl_diff=0, @@ -955,20 +943,8 @@ def test_accounting_overfill_both_vaults( limit = _rebase_limit_wei(block_identifier=chain.height) excess = ETH(10) - web3.manager.request_blocking( - "evm_setAccountBalance", # type: ignore - [ - withdrawal_vault.address, - Web3.to_hex(limit + excess), - ], - ) - web3.manager.request_blocking( - "evm_setAccountBalance", # type: ignore - [ - el_vault.address, - Web3.to_hex(limit + excess), - ], - ) + set_balance_in_wei(withdrawal_vault.address, limit + excess) + set_balance_in_wei(el_vault.address, limit + excess) initial_block = chain.height diff --git a/utils/balance.py b/utils/balance.py index 82f57a65e..0f890729a 100644 --- a/utils/balance.py +++ b/utils/balance.py @@ -1,9 +1,9 @@ from brownie import accounts, web3 from utils.test.helpers import ETH -def set_balance(address, balanceInEth): + +def set_balance_in_wei(address, balance): account = accounts.at(address, force=True) - balance = ETH(balanceInEth) if account.balance() != balance: # try Ganache @@ -18,5 +18,10 @@ def set_balance(address, balanceInEth): except: pass - assert account.balance() == ETH(balanceInEth) + assert account.balance() == balance return account + +def set_balance(address, balanceInEth): + balance = ETH(balanceInEth) + + set_balance_in_wei(address, balance) From 33e5a1187c9ecc11fff103ab65db1053dd777294 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 23 Jul 2024 13:05:01 +0200 Subject: [PATCH 082/220] test: nor.updateTargetValidatorsLimits specify method signature Contract has more than one function 'NodeOperatorsRegistry.updateTargetValidatorsLimits' requiring 3 arguments. --- .../test_accounting_oracle_extra_data_full_items.py | 2 +- tests/regression/test_staking_module_happy_path.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 0b245942d..7507d00e0 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -274,7 +274,7 @@ def fill_nor_with_old_and_new_operators( ) # Change staking limits for old node operators (change to new total added keys count) nor.setNodeOperatorStakingLimit(i, new_deposit_limit, {"from": evm_script_executor_eoa}) - nor.updateTargetValidatorsLimits(i, 1, new_deposit_limit, {"from": contracts.staking_router}) + nor.updateTargetValidatorsLimits['uint256,uint256,uint256'](i, 1, new_deposit_limit, {"from": contracts.staking_router}) return nor_count_before, added_nor_operators_count diff --git a/tests/regression/test_staking_module_happy_path.py b/tests/regression/test_staking_module_happy_path.py index e297ed3a8..14032acfd 100644 --- a/tests/regression/test_staking_module_happy_path.py +++ b/tests/regression/test_staking_module_happy_path.py @@ -773,7 +773,7 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e assert first_no_summary_before["depositableValidatorsCount"] > 0 - target_limit_tx = staking_module.updateTargetValidatorsLimits(no1_id, 1, 0, {"from": STAKING_ROUTER}) + target_limit_tx = staking_module.updateTargetValidatorsLimits['uint256,uint256,uint256'](no1_id, 1, 0, {"from": STAKING_ROUTER}) helpers.assert_single_event_named( "TargetValidatorsCountChanged", @@ -802,7 +802,7 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e assert no3_deposited_keys_before != no3_deposited_keys_after # Disable target limit - target_limit_tx = staking_module.updateTargetValidatorsLimits(no1_id, 0, 0, {"from": STAKING_ROUTER}) + target_limit_tx = staking_module.updateTargetValidatorsLimits['uint256,uint256,uint256'](no1_id, 0, 0, {"from": STAKING_ROUTER}) helpers.assert_single_event_named( "TargetValidatorsCountChanged", From ea7d49a64ca84ec74212558d575dc9d50d6b2c74 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 23 Jul 2024 17:20:30 +0200 Subject: [PATCH 083/220] test: return account from set_balance --- utils/balance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/balance.py b/utils/balance.py index 0f890729a..357333c1b 100644 --- a/utils/balance.py +++ b/utils/balance.py @@ -24,4 +24,4 @@ def set_balance_in_wei(address, balance): def set_balance(address, balanceInEth): balance = ETH(balanceInEth) - set_balance_in_wei(address, balance) + return set_balance_in_wei(address, balance) From 7ba295b898a8d2b1c557feed60cddd48f81d3c6d Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 24 Jul 2024 16:13:49 +0200 Subject: [PATCH 084/220] test: anvil fix enact motion --- utils/test/easy_track_helpers.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/utils/test/easy_track_helpers.py b/utils/test/easy_track_helpers.py index 88b0ac1cb..f2b50bb35 100644 --- a/utils/test/easy_track_helpers.py +++ b/utils/test/easy_track_helpers.py @@ -22,11 +22,12 @@ def create_and_enact_motion(easy_track, trusted_caller, factory, calldata, stran motions = easy_track.getMotions() assert len(motions) == len(motions_before) + 1 - chain.sleep(60 * 60 * 24 * 3) - chain.mine() + (motion_id, _, _, motion_duration, motion_start_date, _, _, _, _,)= motions[-1] + + chain.mine(1, motion_start_date + motion_duration + 1) easy_track.enactMotion( - motions[-1][0], + motion_id, tx.events["MotionCreated"]["_evmScriptCallData"], {"from": stranger}, ) From e1523391985b6d8138fa00cc79686705533582d6 Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 25 Jul 2024 15:25:18 +0200 Subject: [PATCH 085/220] test: update sanity checker permissions --- interfaces/OracleReportSanityChecker.json | 72 +++++++++++------------ tests/regression/test_permissions.py | 4 +- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/interfaces/OracleReportSanityChecker.json b/interfaces/OracleReportSanityChecker.json index b6ec86fbe..a8fcf1214 100644 --- a/interfaces/OracleReportSanityChecker.json +++ b/interfaces/OracleReportSanityChecker.json @@ -40,12 +40,12 @@ }, { "internalType": "uint256", - "name": "maxAccountingExtraDataListItemsCount", + "name": "maxItemsPerExtraDataTransaction", "type": "uint256" }, { "internalType": "uint256", - "name": "maxNodeOperatorsPerExtraDataItemCount", + "name": "maxNodeOperatorsPerExtraDataItem", "type": "uint256" }, { @@ -254,22 +254,6 @@ "name": "IncorrectWithdrawalsVaultBalance", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "maxItemsCount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "receivedItemsCount", - "type": "uint256" - } - ], - "name": "MaxAccountingExtraDataItemsCountExceeded", - "type": "error" - }, { "inputs": [ { @@ -327,6 +311,22 @@ "name": "TooLowTokenRebaseLimit", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxItemsCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedItemsCount", + "type": "uint256" + } + ], + "name": "TooManyItemsPerExtraDataTransaction", + "type": "error" + }, { "inputs": [ { @@ -427,11 +427,11 @@ { "indexed": false, "internalType": "uint256", - "name": "maxAccountingExtraDataListItemsCount", + "name": "maxItemsPerExtraDataTransaction", "type": "uint256" } ], - "name": "MaxAccountingExtraDataListItemsCountSet", + "name": "MaxItemsPerExtraDataTransactionSet", "type": "event" }, { @@ -440,11 +440,11 @@ { "indexed": false, "internalType": "uint256", - "name": "maxNodeOperatorsPerExtraDataItemCount", + "name": "maxNodeOperatorsPerExtraDataItem", "type": "uint256" } ], - "name": "MaxNodeOperatorsPerExtraDataItemCountSet", + "name": "MaxNodeOperatorsPerExtraDataItemSet", "type": "event" }, { @@ -485,7 +485,7 @@ { "indexed": false, "internalType": "uint256", - "name": "clBalance", + "name": "clTotalBalance", "type": "uint256" }, { @@ -497,7 +497,7 @@ { "indexed": false, "internalType": "uint256", - "name": "clBalanceMaxDecrease", + "name": "maxAllowedCLRebaseNegativeSum", "type": "uint256" } ], @@ -723,7 +723,7 @@ }, { "inputs": [], - "name": "MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE", + "name": "MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION_ROLE", "outputs": [ { "internalType": "bytes32", @@ -736,7 +736,7 @@ }, { "inputs": [], - "name": "MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE", + "name": "MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_ROLE", "outputs": [ { "internalType": "bytes32", @@ -1027,12 +1027,12 @@ }, { "internalType": "uint256", - "name": "maxAccountingExtraDataListItemsCount", + "name": "maxItemsPerExtraDataTransaction", "type": "uint256" }, { "internalType": "uint256", - "name": "maxNodeOperatorsPerExtraDataItemCount", + "name": "maxNodeOperatorsPerExtraDataItem", "type": "uint256" }, { @@ -1325,11 +1325,11 @@ "inputs": [ { "internalType": "uint256", - "name": "_maxAccountingExtraDataListItemsCount", + "name": "_maxValidatorExitRequestsPerReport", "type": "uint256" } ], - "name": "setMaxAccountingExtraDataListItemsCount", + "name": "setMaxExitRequestsPerOracleReport", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1338,11 +1338,11 @@ "inputs": [ { "internalType": "uint256", - "name": "_maxValidatorExitRequestsPerReport", + "name": "_maxItemsPerExtraDataTransaction", "type": "uint256" } ], - "name": "setMaxExitRequestsPerOracleReport", + "name": "setMaxItemsPerExtraDataTransaction", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1351,11 +1351,11 @@ "inputs": [ { "internalType": "uint256", - "name": "_maxNodeOperatorsPerExtraDataItemCount", + "name": "_maxNodeOperatorsPerExtraDataItem", "type": "uint256" } ], - "name": "setMaxNodeOperatorsPerExtraDataItemCount", + "name": "setMaxNodeOperatorsPerExtraDataItem", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1404,12 +1404,12 @@ }, { "internalType": "uint256", - "name": "maxAccountingExtraDataListItemsCount", + "name": "maxItemsPerExtraDataTransaction", "type": "uint256" }, { "internalType": "uint256", - "name": "maxNodeOperatorsPerExtraDataItemCount", + "name": "maxNodeOperatorsPerExtraDataItem", "type": "uint256" }, { diff --git a/tests/regression/test_permissions.py b/tests/regression/test_permissions.py index d61838235..d288b9840 100644 --- a/tests/regression/test_permissions.py +++ b/tests/regression/test_permissions.py @@ -165,8 +165,8 @@ def protocol_permissions(): "ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE": [], "SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE": [], "MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT_ROLE": [], - "MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE": [], - "MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE": [], + "MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION_ROLE": [], + "MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_ROLE": [], "REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE": [], "MAX_POSITIVE_TOKEN_REBASE_MANAGER_ROLE": [], "SECOND_OPINION_MANAGER_ROLE": [], From 640a1805a7ea3d8c8ac66cbf58bda1d8d337099c Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 25 Jul 2024 15:46:47 +0200 Subject: [PATCH 086/220] test: rename sanity checker limits --- configs/config_mainnet.py | 4 ++-- .../acceptance/test_accounting_oracle_negative.py | 6 +++--- .../test_oracle_report_sanity_checker.py | 8 ++++---- ...test_accounting_oracle_extra_data_full_items.py | 8 ++++---- tests/regression/test_sanity_checks.py | 14 +++++++------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 05b3e69c1..5b43f7cd8 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -178,8 +178,8 @@ ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT = 50 # 0.5% MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT = 600 -MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT = 8 -MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT = 62 +MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION = 8 +MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM = 62 REQUEST_TIMESTAMP_MARGIN = 7680 # 2 hours rounded to epoch length MAX_POSITIVE_TOKEN_REBASE = 750000 INITIAL_SLASHING_AMOUNT_PWEI = 1000 diff --git a/tests/acceptance/test_accounting_oracle_negative.py b/tests/acceptance/test_accounting_oracle_negative.py index a4c523f2f..bc79c3784 100644 --- a/tests/acceptance/test_accounting_oracle_negative.py +++ b/tests/acceptance/test_accounting_oracle_negative.py @@ -5,7 +5,7 @@ import pytest from brownie import ZERO_ADDRESS, Contract, MockHashConsensus, accounts, chain, interface, reverts, chain # type: ignore from brownie.network.account import Account -from configs.config_mainnet import MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT +from configs.config_mainnet import MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION from utils.config import contracts, ACCOUNTING_ORACLE from utils.evm_script import encode_error @@ -303,7 +303,7 @@ def test_unexpected_extra_data_item(self, extra_data_service: ExtraDataService) extra_data = extra_data_service.collect( {(1, 38): 1}, {(1, 33): 250}, - MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, + MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, 1, ) @@ -330,7 +330,7 @@ def test_already_processed( extra_data = extra_data_service.collect( {(1, 38): 1}, {(1, 33): 250}, - MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, + MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, 1, ) diff --git a/tests/acceptance/test_oracle_report_sanity_checker.py b/tests/acceptance/test_oracle_report_sanity_checker.py index 86a50e443..3e6b222c2 100644 --- a/tests/acceptance/test_oracle_report_sanity_checker.py +++ b/tests/acceptance/test_oracle_report_sanity_checker.py @@ -9,8 +9,8 @@ ANNUAL_BALANCE_INCREASE_BP_LIMIT, SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT, MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT, - MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, - MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT, + MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, REQUEST_TIMESTAMP_MARGIN, MAX_POSITIVE_TOKEN_REBASE, INITIAL_SLASHING_AMOUNT_PWEI, @@ -25,8 +25,8 @@ "annualBalanceIncreaseBPLimit": ANNUAL_BALANCE_INCREASE_BP_LIMIT, "simulatedShareRateDeviationBPLimit": SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT, "maxValidatorExitRequestsPerReport": MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT, - "maxAccountingExtraDataListItemsCount": MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, - "maxNodeOperatorsPerExtraDataItemCount": MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT, + "maxAccountingExtraDataListItemsCount": MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + "maxNodeOperatorsPerExtraDataItemCount": MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, "requestTimestampMargin": REQUEST_TIMESTAMP_MARGIN, "maxPositiveTokenRebase": MAX_POSITIVE_TOKEN_REBASE, "initialSlashingAmountPWei": INITIAL_SLASHING_AMOUNT_PWEI, diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 7507d00e0..2e5ad8e4f 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -10,7 +10,7 @@ from utils.test.oracle_report_helpers import oracle_report from utils.test.node_operators_helpers import distribute_reward -from utils.config import MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT +from utils.config import MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM from utils.config import contracts from utils.test.simple_dvt_helpers import simple_dvt_add_node_operators, simple_dvt_add_keys, simple_dvt_vet_keys @@ -68,7 +68,7 @@ def test_extra_data_full_items( stranger, voting_eoa, agent_eoa, evm_script_executor_eoa, nor, sdvt, extra_data_service, nor_stuck_items, nor_exited_items, sdvt_stuck_items, sdvt_exited_items ): - max_node_operators_per_item = MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT + max_node_operators_per_item = MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM new_keys_per_operator = 2 # Fill NOR with new operators and keys @@ -106,8 +106,8 @@ def test_extra_data_full_items( extra_data = extra_data_service.collect( {**nor_stuck, **sdvt_stuck}, {**nor_exited, **sdvt_exited}, - MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, - MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT, + MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, ) modules_with_exited = [] num_exited_validators_by_staking_module = [] diff --git a/tests/regression/test_sanity_checks.py b/tests/regression/test_sanity_checks.py index 263bb442b..641655538 100644 --- a/tests/regression/test_sanity_checks.py +++ b/tests/regression/test_sanity_checks.py @@ -18,8 +18,8 @@ EXITED_VALIDATORS_PER_DAY_LIMIT, ANNUAL_BALANCE_INCREASE_BP_LIMIT, MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT, - MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, - MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT, + MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, REQUEST_TIMESTAMP_MARGIN, SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT, ) @@ -211,7 +211,7 @@ def test_report_deviated_simulated_share_rate(steth_holder): def test_accounting_oracle_too_much_extra_data(extra_data_service): - item_count = MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT + 1 + item_count = MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION + 1 operators = {} nor_module_id = 1 @@ -227,8 +227,8 @@ def test_accounting_oracle_too_much_extra_data(extra_data_service): with reverts( encode_error( - "MaxAccountingExtraDataItemsCountExceeded(uint256,uint256)", - [MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT, item_count], + "TooManyItemsPerExtraDataTransaction(uint256,uint256)", + [MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, item_count], ) ): oracle_report( @@ -241,12 +241,12 @@ def test_accounting_oracle_too_much_extra_data(extra_data_service): @pytest.mark.skip("ganache throws 'RPCRequestError: Invalid string length' on such long extra data") def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): - item_count = MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT * 10 + item_count = MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM * 10 extra_data = extra_data_service.collect({(1, i): i for i in range(item_count)}, {}, 1, item_count) with reverts( encode_error( "TooManyNodeOpsPerExtraDataItem(uint256,uint256)", - [MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT, item_count], + [MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, item_count], ) ): oracle_report( From a86518b21d936ff4785a39bc00feea0c636a8594 Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 25 Jul 2024 18:09:41 +0200 Subject: [PATCH 087/220] test: update SimpleDVT interface --- interfaces/SimpleDVT.json | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/interfaces/SimpleDVT.json b/interfaces/SimpleDVT.json index bbff81661..4e15f855d 100644 --- a/interfaces/SimpleDVT.json +++ b/interfaces/SimpleDVT.json @@ -884,6 +884,28 @@ "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "name": "_nodeOperatorId", + "type": "uint256" + }, + { + "name": "_isTargetLimitActive", + "type": "bool" + }, + { + "name": "_targetLimit", + "type": "uint256" + } + ], + "name": "updateTargetValidatorsLimits", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ From 19ad57df5d3bd70006e042a903f0a50eea691d4f Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 26 Jul 2024 14:10:17 +0200 Subject: [PATCH 088/220] feat: create permissions for overloaded method --- scripts/mainnet/vote_sr_v2_mainnet.py | 4 ++-- utils/easy_track.py | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/mainnet/vote_sr_v2_mainnet.py b/scripts/mainnet/vote_sr_v2_mainnet.py index 219e53821..b5ed6c58a 100644 --- a/scripts/mainnet/vote_sr_v2_mainnet.py +++ b/scripts/mainnet/vote_sr_v2_mainnet.py @@ -60,7 +60,7 @@ add_implementation_to_sdvt_app_repo, ) from utils.permissions import encode_oz_grant_role, encode_oz_revoke_role -from utils.easy_track import add_evmscript_factory, create_permissions, remove_evmscript_factory +from utils.easy_track import add_evmscript_factory, create_permissions, create_permissions_for_overloaded_method, remove_evmscript_factory from utils.kernel import update_app_implementation from utils.voting import bake_vote_items, confirm_vote_script, create_vote @@ -303,7 +303,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T "19. Add Target limit for SDVT factory to ET", add_evmscript_factory( factory=NEW_TARGET_LIMIT_FACTORY, - permissions=(create_permissions(contracts.simple_dvt, "updateTargetValidatorsLimits")), + permissions=(create_permissions_for_overloaded_method(contracts.simple_dvt, "updateTargetValidatorsLimits", ('uint', 'uint', 'uint'))), ), ), # diff --git a/utils/easy_track.py b/utils/easy_track.py index 1fbed534e..0f92cedda 100644 --- a/utils/easy_track.py +++ b/utils/easy_track.py @@ -26,6 +26,13 @@ def remove_evmscript_factory(factory: Contract | str) -> Tuple[str, str]: ) ) +def create_permissions_for_overloaded_method(contract: Contract, method: str, paramethers: Tuple[str, ...] = None) -> str: + method_description = getattr(contract, method) + + if len(method_description.methods) > 0: + return method_description.methods[paramethers].signature[2:] + + return create_permissions(contract, method) def create_permissions(contract: Contract, method: str) -> str: return contract.address + getattr(contract, method).signature[2:] From 8676fc91ec738ffab2435333feace747b67aa9fc Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 26 Jul 2024 14:26:47 +0200 Subject: [PATCH 089/220] fix: combine add address and method signature --- utils/easy_track.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/easy_track.py b/utils/easy_track.py index 0f92cedda..ca04e9146 100644 --- a/utils/easy_track.py +++ b/utils/easy_track.py @@ -30,7 +30,7 @@ def create_permissions_for_overloaded_method(contract: Contract, method: str, pa method_description = getattr(contract, method) if len(method_description.methods) > 0: - return method_description.methods[paramethers].signature[2:] + return contract.address + method_description.methods[paramethers].signature[2:] return create_permissions(contract, method) From 93832401c4ef50d0f62b733878599868622ad9f5 Mon Sep 17 00:00:00 2001 From: maxim Date: Sun, 28 Jul 2024 16:57:48 +0200 Subject: [PATCH 090/220] test: deactivate all operators in sDVT module --- tests/regression/test_sdvt_rewards_happy_path.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/regression/test_sdvt_rewards_happy_path.py b/tests/regression/test_sdvt_rewards_happy_path.py index ad3f9b061..eed4e72a7 100644 --- a/tests/regression/test_sdvt_rewards_happy_path.py +++ b/tests/regression/test_sdvt_rewards_happy_path.py @@ -15,6 +15,8 @@ from utils.test.simple_dvt_helpers import simple_dvt_add_keys, simple_dvt_vet_keys, simple_dvt_add_node_operators from utils.test.staking_router_helpers import StakingModuleStatus, set_staking_module_status from utils.test.oracle_report_helpers import oracle_report +from brownie import convert +from web3 import Web3 @pytest.fixture(scope="module") @@ -64,6 +66,18 @@ def test_rewards_distribution_happy_path(simple_dvt_module_id, cluster_participa """ simple_dvt, staking_router = contracts.simple_dvt, contracts.staking_router lido, deposit_security_module = contracts.lido, contracts.deposit_security_module + voting = contracts.voting + + contracts.acl.grantPermission( + voting, + simple_dvt, + convert.to_uint(Web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE")), + {"from": contracts.voting}, + ) + + # deactivate all node operators in "Simple DVT" module for more precise testing + for x in range(simple_dvt.getNodeOperatorsCount()): + simple_dvt.deactivateNodeOperator(x, {"from": voting}) new_dvt_operator = cluster_participants[0] From 0fbef4d986226e6b1145f68db1262032a1ecc0a0 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 29 Jul 2024 17:42:27 +0200 Subject: [PATCH 091/220] test: accounting oracle finalizeUpgrade_v2 --- tests/acceptance/test_accounting_oracle_negative.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/acceptance/test_accounting_oracle_negative.py b/tests/acceptance/test_accounting_oracle_negative.py index bc79c3784..f514fdc92 100644 --- a/tests/acceptance/test_accounting_oracle_negative.py +++ b/tests/acceptance/test_accounting_oracle_negative.py @@ -177,6 +177,17 @@ def test_setConsensusContract(accounting_oracle: Contract, aragon_agent: Account {"from": aragon_agent}, ) +def test_finalize_upgrade(accounting_oracle: Contract, stranger: Account): + with reverts(encode_error("InvalidContractVersionIncrement()")): + accounting_oracle.finalizeUpgrade_v2( + 1, + {"from": stranger}, + ) + with reverts(encode_error("InvalidContractVersionIncrement()")): + accounting_oracle.finalizeUpgrade_v2( + 2, + {"from": stranger}, + ) class TestSubmitReportExtraDataList: def build_extra_data(self, extra_data_items: List[bytes]) -> bytes: From ce47de9afee9a4148ae694cde0ace002a2bd5539 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 29 Jul 2024 18:30:02 +0200 Subject: [PATCH 092/220] test: NOR finalizeUpgrade_v3 --- tests/acceptance/test_node_operators_registry.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/acceptance/test_node_operators_registry.py b/tests/acceptance/test_node_operators_registry.py index 27f9f6d2d..5138e62fc 100644 --- a/tests/acceptance/test_node_operators_registry.py +++ b/tests/acceptance/test_node_operators_registry.py @@ -61,6 +61,10 @@ def test_finalize_upgrade(contract): CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY, {"from": contracts.voting}, ) + with reverts("UNEXPECTED_CONTRACT_VERSION"): + contract.finalizeUpgrade_v3( + {"from": contracts.voting}, + ) def test_petrified(): @@ -80,6 +84,10 @@ def test_petrified(): CURATED_STAKING_MODULE_STUCK_PENALTY_DELAY, {"from": contracts.voting}, ) + with reverts("CONTRACT_NOT_INITIALIZED"): + contract.finalizeUpgrade_v3( + {"from": contracts.voting}, + ) def test_nor_state(contract): From bbd6cfd5ac5ee5681cd62ee11c13c88e6b24421a Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 29 Jul 2024 18:43:47 +0200 Subject: [PATCH 093/220] test: DSM version --- tests/acceptance/test_dsm.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/acceptance/test_dsm.py b/tests/acceptance/test_dsm.py index e1e8694db..641315402 100644 --- a/tests/acceptance/test_dsm.py +++ b/tests/acceptance/test_dsm.py @@ -20,6 +20,8 @@ def dsm() -> interface.DepositSecurityModule: def test_owner(dsm): assert dsm.getOwner() == contracts.agent +def test_versioned(dsm): + assert dsm.VERSION() == 3 def test_links(dsm): assert dsm.LIDO() == contracts.lido From e9243c5babcd6726567eaa3566b0c674f04c6153 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 29 Jul 2024 18:51:10 +0200 Subject: [PATCH 094/220] test: DSM not paused --- tests/acceptance/test_dsm.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/acceptance/test_dsm.py b/tests/acceptance/test_dsm.py index 641315402..ba4d377d8 100644 --- a/tests/acceptance/test_dsm.py +++ b/tests/acceptance/test_dsm.py @@ -23,6 +23,9 @@ def test_owner(dsm): def test_versioned(dsm): assert dsm.VERSION() == 3 +def test_deposit_paused(dsm): + assert dsm.isDepositsPaused() == False + def test_links(dsm): assert dsm.LIDO() == contracts.lido assert dsm.STAKING_ROUTER() == contracts.staking_router From 0d67c637c882e40be94ee52c5953525d474ada36 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 31 Jul 2024 13:36:33 +0200 Subject: [PATCH 095/220] feat: move vote to root folder --- scripts/{mainnet/vote_sr_v2_mainnet.py => vote_sr_v2.py} | 0 tests/{test_vote_sr_v2_mainnet.py => test_vote_sr_v2.py} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename scripts/{mainnet/vote_sr_v2_mainnet.py => vote_sr_v2.py} (100%) rename tests/{test_vote_sr_v2_mainnet.py => test_vote_sr_v2.py} (100%) diff --git a/scripts/mainnet/vote_sr_v2_mainnet.py b/scripts/vote_sr_v2.py similarity index 100% rename from scripts/mainnet/vote_sr_v2_mainnet.py rename to scripts/vote_sr_v2.py diff --git a/tests/test_vote_sr_v2_mainnet.py b/tests/test_vote_sr_v2.py similarity index 100% rename from tests/test_vote_sr_v2_mainnet.py rename to tests/test_vote_sr_v2.py From c0c21412144f76b59e3a311c2ee184dd9dc69130 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 31 Jul 2024 17:38:03 +0200 Subject: [PATCH 096/220] test: staking router, check new parameters for modules --- configs/config_mainnet.py | 6 ++++++ tests/acceptance/test_staking_router.py | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 5b43f7cd8..31deca0da 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -140,6 +140,9 @@ ) CURATED_STAKING_MODULE_OPERATORS_COUNT = 39 CURATED_STAKING_MODULE_OPERATORS_ACTIVE_COUNT = 37 +CURATED_STAKING_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 10_000 +CURATED_STAKING_MODULE_MAX_DEPOSITS_PER_BLOCK = 50 +CURATED_STAKING_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE = 25 # NodeOperatorsRegistry clone aka SimpleDVT SIMPLE_DVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" @@ -158,6 +161,9 @@ "0x637572617465642d6f6e636861696e2d76310000000000000000000000000000" ) SIMPLE_DVT_VERSION = 3 +SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 10_000 +SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK = 50 +SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE = 25 # OracleDaemonConfig ORACLE_DAEMON_CONFIG = "0xbf05A929c3D7885a6aeAd833a992dA6E5ac23b09" diff --git a/tests/acceptance/test_staking_router.py b/tests/acceptance/test_staking_router.py index 1d886ab65..ed9a0c4b5 100644 --- a/tests/acceptance/test_staking_router.py +++ b/tests/acceptance/test_staking_router.py @@ -18,12 +18,19 @@ CURATED_STAKING_MODULE_TARGET_SHARE_BP, CURATED_STAKING_MODULE_MODULE_FEE_BP, CURATED_STAKING_MODULE_TREASURY_FEE_BP, + CURATED_STAKING_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, + CURATED_STAKING_MODULE_MAX_DEPOSITS_PER_BLOCK, + CURATED_STAKING_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE, WITHDRAWAL_CREDENTIALS, SIMPLE_DVT_MODULE_ID, SIMPLE_DVT_MODULE_MODULE_FEE_BP, SIMPLE_DVT_MODULE_NAME, SIMPLE_DVT_MODULE_TARGET_SHARE_BP, SIMPLE_DVT_MODULE_TREASURY_FEE_BP, + SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, + SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK, + SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE + ) from utils.evm_script import encode_error @@ -103,6 +110,9 @@ def test_staking_modules(contract): assert curated_module["lastDepositAt"] >= 1679672628 assert curated_module["lastDepositBlock"] >= 8705383 assert curated_module["exitedValidatorsCount"] >= 145 + assert curated_module["priorityExitShareThreshold"] == CURATED_STAKING_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD + assert curated_module["maxDepositsPerBlock"] == CURATED_STAKING_MODULE_MAX_DEPOSITS_PER_BLOCK + assert curated_module["minDepositBlockDistance"] == CURATED_STAKING_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE simple_dvt_module = contract.getStakingModule(2) assert simple_dvt_module["id"] == SIMPLE_DVT_MODULE_ID @@ -115,6 +125,9 @@ def test_staking_modules(contract): assert simple_dvt_module["lastDepositAt"] > 0 assert simple_dvt_module["lastDepositBlock"] > 0 assert simple_dvt_module["exitedValidatorsCount"] >= 0 + assert simple_dvt_module["priorityExitShareThreshold"] == SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD + assert simple_dvt_module["maxDepositsPerBlock"] == SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK + assert curated_module["minDepositBlockDistance"] == SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE fee_aggregate_distribution = contract.getStakingFeeAggregateDistribution() assert fee_aggregate_distribution["modulesFee"] <= SR_MODULES_FEE_E20 From b07a55a5cf19372517f42f9a0c78d3842cd312a1 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 31 Jul 2024 17:45:55 +0200 Subject: [PATCH 097/220] test: staking router finalize upgrade v2 --- tests/acceptance/test_staking_router.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/acceptance/test_staking_router.py b/tests/acceptance/test_staking_router.py index ed9a0c4b5..00adcd673 100644 --- a/tests/acceptance/test_staking_router.py +++ b/tests/acceptance/test_staking_router.py @@ -64,6 +64,17 @@ def test_initialize(contract): {"from": contracts.voting}, ) +def test_finalize_upgrade(contract): + with reverts(encode_error( + "UnexpectedContractVersion(uint256,uint256)", + [2, 1], + )): + contract.finalizeUpgrade_v2( + [10_000, 10_000], + [50, 50], + [25, 25], + {"from": contracts.voting}, + ) def test_petrified(contract): impl = interface.StakingRouter(STAKING_ROUTER_IMPL) From ca401a59cec1e72796aa5e20686e57bb1f916c7a Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 31 Jul 2024 18:45:21 +0200 Subject: [PATCH 098/220] test: test_update_target_validators_limits --- .../test_node_operators_registry.py | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/acceptance/test_node_operators_registry.py b/tests/acceptance/test_node_operators_registry.py index 5138e62fc..810d93753 100644 --- a/tests/acceptance/test_node_operators_registry.py +++ b/tests/acceptance/test_node_operators_registry.py @@ -1,5 +1,8 @@ import pytest from brownie import ZERO_ADDRESS, interface, web3, reverts # type: ignore +from brownie.network.account import Account +from brownie import convert +from web3 import Web3 from utils.config import ( contracts, @@ -13,6 +16,13 @@ CURATED_STAKING_MODULE_TYPE, ) +@pytest.fixture +def voting(accounts): + return accounts.at(contracts.voting.address, force=True) + +@pytest.fixture(scope="module") +def agent_eoa(accounts): + return accounts.at(contracts.agent.address, force=True) @pytest.fixture(scope="module") def contract() -> interface.NodeOperatorsRegistry: @@ -146,6 +156,58 @@ def test_nor_state(contract): assert node_operator_summary["depositableValidatorsCount"] == no_depositable_validators_count +def test_update_target_validators_limits(contract, voting, stranger): + operator_id = contract.getNodeOperatorsCount() + + with reverts("APP_AUTH_FAILED"): + contract.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) + + contracts.acl.grantPermission( + stranger, + contract, + convert.to_uint(Web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE")), + {"from": voting}, + ) + + contract.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) + + node_operator = contract.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 0 + assert node_operator["targetValidatorsCount"] == 0 + + with reverts("APP_AUTH_FAILED"): + contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 1, 10, {"from": stranger}) + + contracts.acl.grantPermission( + stranger, + contract, + convert.to_uint(Web3.keccak(text="STAKING_ROUTER_ROLE")), + {"from": voting}, + ) + + with reverts("OUT_OF_RANGE"): + contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id + 1, 1, 10, {"from": stranger}) + + contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 1, 10, {"from": stranger}) + node_operator = contract.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 1 + assert node_operator["targetValidatorsCount"] == 10 + + contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 2, 20, {"from": stranger}) + node_operator = contract.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 2 + assert node_operator["targetValidatorsCount"] == 20 + + # any target mode value great then 2 will be treat as force mode + contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 3, 30, {"from": stranger}) + node_operator = contract.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 3 + assert node_operator["targetValidatorsCount"] == 30 + + contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 0, 40, {"from": stranger}) + node_operator = contract.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 0 + assert node_operator["targetValidatorsCount"] == 0 # should be always 0 in disabled mode def _str_to_bytes32(s: str) -> str: return "0x{:0<64}".format(s.encode("utf-8").hex()) From 84007907a67bf6503aa9ae20b0c638d1cbe28cd6 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Mon, 29 Jul 2024 14:35:48 +0500 Subject: [PATCH 099/220] Add CSM acceptance test suite fixes: - execute a vote before acceptance tests - cache vote state using snapshot for better test execution time --- archive/scripts/vote_sr_v2_holesky.py | 4 +- archive/tests/test_vote_sr_v2_holesky.py | 2 +- configs/config_holesky.py | 8 +- interfaces/csm/CSAccounting.json | 4385 ++++++++++---------- interfaces/csm/CSEarlyAdoption.json | 339 +- interfaces/csm/CSFeeDistributor.json | 1685 ++++---- interfaces/csm/CSFeeOracle.json | 2663 ++++++------ interfaces/csm/CSHashConsensus.json | 1916 +++++---- interfaces/csm/CSModule.json | 4777 ++++++++++++++-------- interfaces/csm/CSVerifier.json | 1356 +++--- scripts/vote_sr_v2.py | 4 +- tests/acceptance/conftest.py | 10 + tests/acceptance/test_csm.py | 205 + tests/test_vote_sr_v2.py | 10 +- utils/config.py | 24 +- utils/import_current_votes.py | 14 +- 16 files changed, 9826 insertions(+), 7576 deletions(-) create mode 100644 tests/acceptance/test_csm.py diff --git a/archive/scripts/vote_sr_v2_holesky.py b/archive/scripts/vote_sr_v2_holesky.py index ee64c8aeb..1ecc2f023 100644 --- a/archive/scripts/vote_sr_v2_holesky.py +++ b/archive/scripts/vote_sr_v2_holesky.py @@ -358,8 +358,8 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T agent_forward( [ ( - contracts.csmHashConsensus.address, - contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), + contracts.csm_hash_consensus.address, + contracts.csm_hash_consensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), ) ] ), diff --git a/archive/tests/test_vote_sr_v2_holesky.py b/archive/tests/test_vote_sr_v2_holesky.py index 7448f8da4..1a05e3736 100644 --- a/archive/tests/test_vote_sr_v2_holesky.py +++ b/archive/tests/test_vote_sr_v2_holesky.py @@ -248,7 +248,7 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): assert contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) - assert contracts.csmHashConsensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + assert contracts.csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH # Events check if bypass_events_decoding: diff --git a/configs/config_holesky.py b/configs/config_holesky.py index ab9826a96..889a5852d 100644 --- a/configs/config_holesky.py +++ b/configs/config_holesky.py @@ -117,6 +117,12 @@ SANDBOX_IMPL = "0x605A3AFadF35A8a8fa4f4Cd4fe34a09Bbcea7718" -CSM = "0x4562c3e63c2e586cD1651B958C22F88135aCAd4f" +CSM_ADDRESS = "0x4562c3e63c2e586cD1651B958C22F88135aCAd4f" CS_ACCOUNTING_ADDRESS = "0xc093e53e8F4b55A223c18A2Da6fA00e60DD5EFE1" CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xbF38618Ea09B503c1dED867156A0ea276Ca1AE37" +CS_EARLY_ADOPTION_ADDRESS = "0x71E92eA77C198a770d9f33A03277DbeB99989660" +CS_FEE_DISTRIBUTOR_ADDRESS = "0xD7ba648C8F72669C6aE649648B516ec03D07c8ED" +CS_FEE_ORACLE_ADDRESS = "0xaF57326C7d513085051b50912D51809ECC5d98Ee" +CS_GATE_SEAL_ADDRESS = "0x41F2677fae0222cF1f08Cd1c0AAa607B469654Ce" +CS_VERIFIER_ADDRESS = "0x6DcA479178E6Ae41CCEB72a88FfDaa3e10E83CB7" +CS_ORACLE_EPOCHS_PER_FRAME = 225 * 7 # 7 days diff --git a/interfaces/csm/CSAccounting.json b/interfaces/csm/CSAccounting.json index 21c97ee94..8dc94bed9 100644 --- a/interfaces/csm/CSAccounting.json +++ b/interfaces/csm/CSAccounting.json @@ -1,2088 +1,2299 @@ [ - { - "type": "constructor", - "inputs": [ - { - "name": "lidoLocator", - "type": "address", - "internalType": "address" - }, - { - "name": "communityStakingModule", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "ACCOUNTING_MANAGER_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "ADD_BOND_CURVE_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "DEFAULT_ADMIN_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "MAX_BOND_LOCK_RETENTION_PERIOD", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "MIN_BOND_LOCK_RETENTION_PERIOD", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "PAUSE_INFINITELY", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "PAUSE_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "RECOVERER_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "RESET_BOND_CURVE_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "RESUME_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "SET_BOND_CURVE_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "SET_DEFAULT_BOND_CURVE_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "addBondCurve", - "inputs": [ - { - "name": "bondCurve", - "type": "uint256[]", - "internalType": "uint256[]" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "chargeFee", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "chargeRecipient", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "claimRewardsStETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "stETHAmount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "cumulativeFeeShares", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "rewardsProof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "claimRewardsWstETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "wstETHAmount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "cumulativeFeeShares", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "rewardsProof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "compensateLockedBondETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "payable" - }, - { - "type": "function", - "name": "defaultBondCurveId", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "depositETH", - "inputs": [ - { - "name": "from", - "type": "address", - "internalType": "address" - }, - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "shares", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "payable" - }, - { - "type": "function", - "name": "depositStETH", - "inputs": [ - { - "name": "from", - "type": "address", - "internalType": "address" - }, - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "stETHAmount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "permit", - "type": "tuple", - "internalType": "struct CSAccounting.PermitInput", - "components": [ - { - "name": "value", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "deadline", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "v", - "type": "uint8", - "internalType": "uint8" - }, - { - "name": "r", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "s", - "type": "bytes32", - "internalType": "bytes32" - } - ] - } - ], - "outputs": [ - { - "name": "shares", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "depositWstETH", - "inputs": [ - { - "name": "from", - "type": "address", - "internalType": "address" - }, - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "wstETHAmount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "permit", - "type": "tuple", - "internalType": "struct CSAccounting.PermitInput", - "components": [ - { - "name": "value", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "deadline", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "v", - "type": "uint8", - "internalType": "uint8" - }, - { - "name": "r", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "s", - "type": "bytes32", - "internalType": "bytes32" - } - ] - } - ], - "outputs": [ - { - "name": "shares", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "feeDistributor", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract ICSFeeDistributor" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getActualLockedBond", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBond", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBondAmountByKeysCount", - "inputs": [ - { - "name": "keys", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "curve", - "type": "tuple", - "internalType": "struct CSBondCurve.BondCurve", - "components": [ - { - "name": "id", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "points", - "type": "uint256[]", - "internalType": "uint256[]" - }, - { - "name": "trend", - "type": "uint256", - "internalType": "uint256" - } - ] - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "pure" - }, - { - "type": "function", - "name": "getBondAmountByKeysCount", - "inputs": [ - { - "name": "keys", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBondAmountByKeysCountWstETH", - "inputs": [ - { - "name": "keysCount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "curve", - "type": "tuple", - "internalType": "struct CSBondCurve.BondCurve", - "components": [ - { - "name": "id", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "points", - "type": "uint256[]", - "internalType": "uint256[]" - }, - { - "name": "trend", - "type": "uint256", - "internalType": "uint256" - } - ] - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBondAmountByKeysCountWstETH", - "inputs": [ - { - "name": "keysCount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBondCurve", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "tuple", - "internalType": "struct CSBondCurve.BondCurve", - "components": [ - { - "name": "id", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "points", - "type": "uint256[]", - "internalType": "uint256[]" - }, - { - "name": "trend", - "type": "uint256", - "internalType": "uint256" - } - ] - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBondLockRetentionPeriod", - "inputs": [], - "outputs": [ - { - "name": "retention", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBondShares", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBondSummary", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "current", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "required", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getBondSummaryShares", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "current", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "required", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getCurveInfo", - "inputs": [ - { - "name": "curveId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "tuple", - "internalType": "struct CSBondCurve.BondCurve", - "components": [ - { - "name": "id", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "points", - "type": "uint256[]", - "internalType": "uint256[]" - }, - { - "name": "trend", - "type": "uint256", - "internalType": "uint256" - } - ] - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getKeysCountByBondAmount", - "inputs": [ - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getKeysCountByBondAmount", - "inputs": [ - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "curve", - "type": "tuple", - "internalType": "struct CSBondCurve.BondCurve", - "components": [ - { - "name": "id", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "points", - "type": "uint256[]", - "internalType": "uint256[]" - }, - { - "name": "trend", - "type": "uint256", - "internalType": "uint256" - } - ] - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "pure" - }, - { - "type": "function", - "name": "getLockedBondInfo", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "tuple", - "internalType": "struct CSBondLock.BondLock", - "components": [ - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "retentionUntil", - "type": "uint256", - "internalType": "uint256" - } - ] - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRequiredBondForNextKeys", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "additionalKeys", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRequiredBondForNextKeysWstETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "additionalKeys", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getResumeSinceTimestamp", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleAdmin", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleMember", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "index", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleMemberCount", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getUnbondedKeysCount", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getUnbondedKeysCountToEject", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "grantRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "hasRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "initialize", - "inputs": [ - { - "name": "bondCurve", - "type": "uint256[]", - "internalType": "uint256[]" - }, - { - "name": "admin", - "type": "address", - "internalType": "address" - }, - { - "name": "_feeDistributor", - "type": "address", - "internalType": "address" - }, - { - "name": "bondLockRetentionPeriod", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "_chargeRecipient", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "isPaused", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "lockBondETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "pauseFor", - "inputs": [ - { - "name": "duration", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "penalize", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC1155", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC20", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC721", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverEther", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverStETHShares", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "releaseLockedBondETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "renounceRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "callerConfirmation", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "requestRewardsETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "ethAmount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "cumulativeFeeShares", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "rewardsProof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "resetBondCurve", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "resume", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "revokeRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setBondCurve", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "curveId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setChargeRecipient", - "inputs": [ - { - "name": "_chargeRecipient", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setDefaultBondCurve", - "inputs": [ - { - "name": "curveId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setLockedBondRetentionPeriod", - "inputs": [ - { - "name": "retention", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "settleLockedBondETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "lockedAmount", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "supportsInterface", - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4", - "internalType": "bytes4" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "totalBondShares", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "event", - "name": "BondBurned", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "toBurnAmount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "burnedAmount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondCharged", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "toChargeAmount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "chargedAmount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondClaimed", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "to", - "type": "address", - "indexed": false, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondClaimedWstETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "to", - "type": "address", - "indexed": false, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondCurveAdded", - "inputs": [ - { - "name": "bondCurve", - "type": "uint256[]", - "indexed": false, - "internalType": "uint256[]" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondCurveChanged", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "curveId", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondDeposited", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "from", - "type": "address", - "indexed": false, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondDepositedWstETH", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "from", - "type": "address", - "indexed": false, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondLockChanged", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "newAmount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "retentionUntil", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondLockCompensated", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "BondLockRetentionPeriodChanged", - "inputs": [ - { - "name": "retentionPeriod", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ChargeRecipientSet", - "inputs": [ - { - "name": "chargeRecipient", - "type": "address", - "indexed": false, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "DefaultBondCurveChanged", - "inputs": [ - { - "name": "curveId", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Initialized", - "inputs": [ - { - "name": "version", - "type": "uint64", - "indexed": false, - "internalType": "uint64" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Paused", - "inputs": [ - { - "name": "duration", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Resumed", - "inputs": [], - "anonymous": false - }, - { - "type": "event", - "name": "RoleAdminChanged", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "previousAdminRole", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "newAdminRole", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleGranted", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleRevoked", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "error", - "name": "AccessControlBadConfirmation", - "inputs": [] - }, - { - "type": "error", - "name": "AccessControlUnauthorizedAccount", - "inputs": [ - { - "name": "account", - "type": "address", - "internalType": "address" - }, - { - "name": "neededRole", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "type": "error", - "name": "AlreadyInitialized", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidBondCurveId", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidBondCurveLength", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidBondCurveValues", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidBondLockAmount", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidBondLockRetentionPeriod", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidClaimableShares", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidInitialization", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidSender", - "inputs": [] - }, - { - "type": "error", - "name": "NotAllowedToRecover", - "inputs": [] - }, - { - "type": "error", - "name": "NotInitializing", - "inputs": [] - }, - { - "type": "error", - "name": "PauseUntilMustBeInFuture", - "inputs": [] - }, - { - "type": "error", - "name": "PausedExpected", - "inputs": [] - }, - { - "type": "error", - "name": "ResumedExpected", - "inputs": [] - }, - { - "type": "error", - "name": "SenderIsNotCSM", - "inputs": [] - }, - { - "type": "error", - "name": "ZeroAddress", - "inputs": [ - { - "name": "field", - "type": "string", - "internalType": "string" - } - ] - }, - { - "type": "error", - "name": "ZeroPauseDuration", - "inputs": [] - }, - { - "type": "event", - "name": "ERC1155Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ERC20Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ERC721Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "EtherRecovered", - "inputs": [ - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "StETHSharesRecovered", - "inputs": [ - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "shares", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "error", - "name": "AddressEmptyCode", - "inputs": [ - { - "name": "target", - "type": "address", - "internalType": "address" - } - ] - }, - { - "type": "error", - "name": "AddressInsufficientBalance", - "inputs": [ - { - "name": "account", - "type": "address", - "internalType": "address" - } - ] - }, - { - "type": "error", - "name": "FailedInnerCall", - "inputs": [] - }, - { - "type": "error", - "name": "FailedToSendEther", - "inputs": [] - }, - { - "type": "error", - "name": "SafeERC20FailedOperation", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - } - ] - } -] \ No newline at end of file + { + "type": "constructor", + "inputs": [ + { + "name": "lidoLocator", + "type": "address", + "internalType": "address" + }, + { + "name": "communityStakingModule", + "type": "address", + "internalType": "address" + }, + { + "name": "maxCurveLength", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "minBondLockRetentionPeriod", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxBondLockRetentionPeriod", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "ACCOUNTING_MANAGER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "CSM", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSModule" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_BOND_CURVE_ID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "LIDO", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ILido" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "LIDO_LOCATOR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ILidoLocator" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_BOND_CURVES_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MAX_BOND_LOCK_RETENTION_PERIOD", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MAX_CURVE_LENGTH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MIN_BOND_LOCK_RETENTION_PERIOD", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MIN_CURVE_LENGTH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_INFINITELY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RECOVERER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RESET_BOND_CURVE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RESUME_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SET_BOND_CURVE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "WITHDRAWAL_QUEUE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IWithdrawalQueue" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "WSTETH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IWstETH" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addBondCurve", + "inputs": [ + { + "name": "bondCurve", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "outputs": [ + { + "name": "id", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "chargeFee", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "chargePenaltyRecipient", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "claimRewardsStETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewardsUnstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stEthAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewardsWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "wstETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "compensateLockedBondETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "depositETH", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "depositStETH", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct ICSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "depositWstETH", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "wstETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct ICSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "feeDistributor", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSFeeDistributor" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getActualLockedBond", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBond", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondAmountByKeysCount", + "inputs": [ + { + "name": "keys", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curve", + "type": "tuple", + "internalType": "struct ICSBondCurve.BondCurve", + "components": [ + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getBondAmountByKeysCount", + "inputs": [ + { + "name": "keys", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondAmountByKeysCountWstETH", + "inputs": [ + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondAmountByKeysCountWstETH", + "inputs": [ + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curve", + "type": "tuple", + "internalType": "struct ICSBondCurve.BondCurve", + "components": [ + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondCurve", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct ICSBondCurve.BondCurve", + "components": [ + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondCurveId", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondLockRetentionPeriod", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondShares", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondSummary", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "current", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "required", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBondSummaryShares", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "current", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "required", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getCurveInfo", + "inputs": [ + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct ICSBondCurve.BondCurve", + "components": [ + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getKeysCountByBondAmount", + "inputs": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curve", + "type": "tuple", + "internalType": "struct ICSBondCurve.BondCurve", + "components": [ + { + "name": "points", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "trend", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getKeysCountByBondAmount", + "inputs": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLockedBondInfo", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct ICSBondLock.BondLock", + "components": [ + { + "name": "amount", + "type": "uint128", + "internalType": "uint128" + }, + { + "name": "retentionUntil", + "type": "uint128", + "internalType": "uint128" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRequiredBondForNextKeys", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "additionalKeys", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRequiredBondForNextKeysWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "additionalKeys", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getResumeSinceTimestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUnbondedKeysCount", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUnbondedKeysCountToEject", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "bondCurve", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "admin", + "type": "address", + "internalType": "address" + }, + { + "name": "_feeDistributor", + "type": "address", + "internalType": "address" + }, + { + "name": "bondLockRetentionPeriod", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_chargePenaltyRecipient", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isPaused", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lockBondETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pauseFor", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "penalize", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pullFeeRewards", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC1155", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC20", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC721", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverEther", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverStETHShares", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "releaseLockedBondETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renewBurnerAllowance", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resetBondCurve", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resume", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setBondCurve", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setChargePenaltyRecipient", + "inputs": [ + { + "name": "_chargePenaltyRecipient", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setLockedBondRetentionPeriod", + "inputs": [ + { + "name": "retention", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "settleLockedBondETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "settledAmount", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalBondShares", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "updateBondCurve", + "inputs": [ + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bondCurve", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "BondBurned", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "toBurnAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "burnedAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondCharged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "toChargeAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "chargedAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondClaimedStETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "to", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondClaimedUnstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "to", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "requestId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondClaimedWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "to", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondCurveAdded", + "inputs": [ + { + "name": "bondCurve", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondCurveSet", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "curveId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondCurveUpdated", + "inputs": [ + { + "name": "curveId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "bondCurve", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondDepositedETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "from", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondDepositedStETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "from", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondDepositedWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "from", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondLockChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "newAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "retentionUntil", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondLockCompensated", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondLockRemoved", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BondLockRetentionPeriodChanged", + "inputs": [ + { + "name": "retentionPeriod", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ChargePenaltyRecipientSet", + "inputs": [ + { + "name": "chargePenaltyRecipient", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC1155Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC20Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC721Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EtherRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Resumed", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StETHSharesRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "ElRewardsVaultReceiveFailed", + "inputs": [] + }, + { + "type": "error", + "name": "FailedToSendEther", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondCurveId", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondCurveLength", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondCurveMaxLength", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondCurveValues", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondLockAmount", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBondLockRetentionPeriod", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialisationCurveId", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "NodeOperatorDoesNotExist", + "inputs": [] + }, + { + "type": "error", + "name": "NotAllowedToRecover", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "NothingToClaim", + "inputs": [] + }, + { + "type": "error", + "name": "PauseUntilMustBeInFuture", + "inputs": [] + }, + { + "type": "error", + "name": "PausedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "ResumedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "SafeCastOverflowedUintDowncast", + "inputs": [ + { + "name": "bits", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "SenderIsNotCSM", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAdminAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroChargePenaltyRecipientAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroFeeDistributorAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroLocatorAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroModuleAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroPauseDuration", + "inputs": [] + } + ] diff --git a/interfaces/csm/CSEarlyAdoption.json b/interfaces/csm/CSEarlyAdoption.json index c538fd3eb..81753384c 100644 --- a/interfaces/csm/CSEarlyAdoption.json +++ b/interfaces/csm/CSEarlyAdoption.json @@ -1,156 +1,185 @@ [ - { - "type": "constructor", - "inputs": [ - { - "name": "_treeRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "_curveId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "_module", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "consume", - "inputs": [ - { - "name": "sender", - "type": "address", - "internalType": "address" - }, - { - "name": "proof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "consumed", - "inputs": [ - { - "name": "sender", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "curveId", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "isEligible", - "inputs": [ - { - "name": "sender", - "type": "address", - "internalType": "address" - }, - { - "name": "proof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "module", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "treeRoot", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "event", - "name": "Consumed", - "inputs": [ - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "error", - "name": "AlreadyConsumed", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidProof", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidValue", - "inputs": [] - }, - { - "type": "error", - "name": "OnlyModule", - "inputs": [] - } -] \ No newline at end of file + { + "type": "constructor", + "inputs": [ + { + "name": "treeRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "curveId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "module", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "CURVE_ID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MODULE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "TREE_ROOT", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "consume", + "inputs": [ + { + "name": "member", + "type": "address", + "internalType": "address" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hashLeaf", + "inputs": [ + { + "name": "member", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "isConsumed", + "inputs": [ + { + "name": "member", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "verifyProof", + "inputs": [ + { + "name": "member", + "type": "address", + "internalType": "address" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "Consumed", + "inputs": [ + { + "name": "member", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AlreadyConsumed", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidCurveId", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidProof", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidTreeRoot", + "inputs": [] + }, + { + "type": "error", + "name": "SenderIsNotModule", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroModuleAddress", + "inputs": [] + } + ] diff --git a/interfaces/csm/CSFeeDistributor.json b/interfaces/csm/CSFeeDistributor.json index 41b8377a4..26a88ba29 100644 --- a/interfaces/csm/CSFeeDistributor.json +++ b/interfaces/csm/CSFeeDistributor.json @@ -1,838 +1,849 @@ [ - { - "type": "constructor", - "inputs": [ - { - "name": "stETH", - "type": "address", - "internalType": "address" - }, - { - "name": "accounting", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "ACCOUNTING", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "DEFAULT_ADMIN_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "ORACLE_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "RECOVERER_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "STETH", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract IStETH" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "claimableShares", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "distributeFees", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "shares", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "proof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "distributedShares", - "inputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getFeesToDistribute", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "shares", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "proof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleAdmin", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleMember", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "index", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleMemberCount", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "grantRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "hasRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "hashLeaf", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "shares", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "pure" - }, - { - "type": "function", - "name": "initialize", - "inputs": [ - { - "name": "admin", - "type": "address", - "internalType": "address" - }, - { - "name": "oracle", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "pendingToDistribute", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "processOracleReport", - "inputs": [ - { - "name": "_treeRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "_treeCid", - "type": "string", - "internalType": "string" - }, - { - "name": "distributed", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC1155", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC20", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC721", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverEther", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "renounceRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "callerConfirmation", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "revokeRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "supportsInterface", - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4", - "internalType": "bytes4" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "treeCid", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "string", - "internalType": "string" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "treeRoot", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "event", - "name": "FeeDistributed", - "inputs": [ - { - "name": "nodeOperatorId", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "shares", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Initialized", - "inputs": [ - { - "name": "version", - "type": "uint64", - "indexed": false, - "internalType": "uint64" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleAdminChanged", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "previousAdminRole", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "newAdminRole", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleGranted", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleRevoked", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "error", - "name": "AccessControlBadConfirmation", - "inputs": [] - }, - { - "type": "error", - "name": "AccessControlUnauthorizedAccount", - "inputs": [ - { - "name": "account", - "type": "address", - "internalType": "address" - }, - { - "name": "neededRole", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "type": "error", - "name": "InvalidInitialization", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidProof", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidShares", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidTreeCID", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidTreeRoot", - "inputs": [] - }, - { - "type": "error", - "name": "NotAccounting", - "inputs": [] - }, - { - "type": "error", - "name": "NotAllowedToRecover", - "inputs": [] - }, - { - "type": "error", - "name": "NotInitializing", - "inputs": [] - }, - { - "type": "error", - "name": "ZeroAddress", - "inputs": [ - { - "name": "field", - "type": "string", - "internalType": "string" - } - ] - }, - { - "type": "event", - "name": "ERC1155Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ERC20Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ERC721Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "EtherRecovered", - "inputs": [ - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "StETHSharesRecovered", - "inputs": [ - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "shares", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "error", - "name": "AddressEmptyCode", - "inputs": [ - { - "name": "target", - "type": "address", - "internalType": "address" - } - ] - }, - { - "type": "error", - "name": "AddressInsufficientBalance", - "inputs": [ - { - "name": "account", - "type": "address", - "internalType": "address" - } - ] - }, - { - "type": "error", - "name": "FailedInnerCall", - "inputs": [] - }, - { - "type": "error", - "name": "FailedToSendEther", - "inputs": [] - }, - { - "type": "error", - "name": "SafeERC20FailedOperation", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - } - ] - } -] \ No newline at end of file + { + "type": "constructor", + "inputs": [ + { + "name": "stETH", + "type": "address", + "internalType": "address" + }, + { + "name": "accounting", + "type": "address", + "internalType": "address" + }, + { + "name": "oracle", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "ACCOUNTING", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ORACLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RECOVERER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "STETH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IStETH" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "distributeFees", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [ + { + "name": "sharesToDistribute", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "distributedShares", + "inputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getFeesToDistribute", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [ + { + "name": "sharesToDistribute", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "hashLeaf", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "admin", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pendingSharesToDistribute", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "processOracleReport", + "inputs": [ + { + "name": "_treeRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "_treeCid", + "type": "string", + "internalType": "string" + }, + { + "name": "distributed", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC1155", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC20", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC721", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverEther", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalClaimableShares", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "treeCid", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "treeRoot", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "DistributionDataUpdated", + "inputs": [ + { + "name": "totalClaimableShares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "treeRoot", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "treeCid", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC1155Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC20Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC721Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EtherRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeeDistributed", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StETHSharesRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "FailedToSendEther", + "inputs": [] + }, + { + "type": "error", + "name": "FeeSharesDecrease", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidProof", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidShares", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidTreeCID", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidTreeRoot", + "inputs": [] + }, + { + "type": "error", + "name": "NotAccounting", + "inputs": [] + }, + { + "type": "error", + "name": "NotAllowedToRecover", + "inputs": [] + }, + { + "type": "error", + "name": "NotEnoughShares", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "NotOracle", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAccountingAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAdminAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroOracleAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroStEthAddress", + "inputs": [] + } + ] diff --git a/interfaces/csm/CSFeeOracle.json b/interfaces/csm/CSFeeOracle.json index b4470d5dc..1b56f6a41 100644 --- a/interfaces/csm/CSFeeOracle.json +++ b/interfaces/csm/CSFeeOracle.json @@ -1,1268 +1,1397 @@ [ - { - "type": "constructor", - "inputs": [ - { - "name": "secondsPerSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "genesisTime", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "CONTRACT_MANAGER_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "DEFAULT_ADMIN_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "GENESIS_TIME", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "MANAGE_CONSENSUS_CONTRACT_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "MANAGE_CONSENSUS_VERSION_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "PAUSE_INFINITELY", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "PAUSE_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "RECOVERER_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "RESUME_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "SECONDS_PER_SLOT", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "SUBMIT_DATA_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "discardConsensusReport", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "feeDistributor", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract ICSFeeDistributor" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getConsensusContract", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getConsensusReport", - "inputs": [], - "outputs": [ - { - "name": "hash", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "processingDeadlineTime", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "processingStarted", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getConsensusVersion", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getContractVersion", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getLastProcessingRefSlot", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getResumeSinceTimestamp", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleAdmin", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleMember", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "index", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleMemberCount", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "grantRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "hasRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "initialize", - "inputs": [ - { - "name": "admin", - "type": "address", - "internalType": "address" - }, - { - "name": "feeDistributorContract", - "type": "address", - "internalType": "address" - }, - { - "name": "consensusContract", - "type": "address", - "internalType": "address" - }, - { - "name": "consensusVersion", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "_perfThresholdBP", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "isPaused", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "pauseFor", - "inputs": [ - { - "name": "duration", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "pauseUntil", - "inputs": [ - { - "name": "pauseUntilInclusive", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "perfThresholdBP", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "recoverERC1155", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC20", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC721", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverEther", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "renounceRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "callerConfirmation", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "resume", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "revokeRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setConsensusContract", - "inputs": [ - { - "name": "addr", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setConsensusVersion", - "inputs": [ - { - "name": "version", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setFeeDistributorContract", - "inputs": [ - { - "name": "feeDistributorContract", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setPerformanceThreshold", - "inputs": [ - { - "name": "valueBP", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "submitConsensusReport", - "inputs": [ - { - "name": "reportHash", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "deadline", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "submitReportData", - "inputs": [ - { - "name": "data", - "type": "tuple", - "internalType": "struct CSFeeOracle.ReportData", - "components": [ - { - "name": "consensusVersion", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "treeRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "treeCid", - "type": "string", - "internalType": "string" - }, - { - "name": "distributed", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "name": "contractVersion", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "supportsInterface", - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4", - "internalType": "bytes4" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "event", - "name": "ConsensusHashContractSet", - "inputs": [ - { - "name": "addr", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "prevAddr", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ConsensusVersionSet", - "inputs": [ - { - "name": "version", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "prevVersion", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ContractVersionSet", - "inputs": [ - { - "name": "version", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "FeeDistributorContractSet", - "inputs": [ - { - "name": "feeDistributorContract", - "type": "address", - "indexed": false, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Initialized", - "inputs": [ - { - "name": "version", - "type": "uint64", - "indexed": false, - "internalType": "uint64" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Paused", - "inputs": [ - { - "name": "duration", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "PerformanceThresholdSet", - "inputs": [ - { - "name": "valueBP", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ProcessingStarted", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "hash", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ReportConsolidated", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "distributed", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "newRoot", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - }, - { - "name": "treeCid", - "type": "string", - "indexed": false, - "internalType": "string" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ReportDiscarded", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "hash", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ReportSubmitted", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "hash", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - }, - { - "name": "processingDeadlineTime", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Resumed", - "inputs": [], - "anonymous": false - }, - { - "type": "event", - "name": "RoleAdminChanged", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "previousAdminRole", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "newAdminRole", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleGranted", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleRevoked", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "WarnProcessingMissed", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "error", - "name": "AccessControlBadConfirmation", - "inputs": [] - }, - { - "type": "error", - "name": "AccessControlUnauthorizedAccount", - "inputs": [ - { - "name": "account", - "type": "address", - "internalType": "address" - }, - { - "name": "neededRole", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "type": "error", - "name": "AddressCannotBeSame", - "inputs": [] - }, - { - "type": "error", - "name": "AddressCannotBeZero", - "inputs": [] - }, - { - "type": "error", - "name": "AdminCannotBeZero", - "inputs": [] - }, - { - "type": "error", - "name": "HashCannotBeZero", - "inputs": [] - }, - { - "type": "error", - "name": "InitialRefSlotCannotBeLessThanProcessingOne", - "inputs": [ - { - "name": "initialRefSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "processingRefSlot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "InvalidContractVersionIncrement", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidInitialization", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidPerfThreshold", - "inputs": [] - }, - { - "type": "error", - "name": "NoConsensusReportToProcess", - "inputs": [] - }, - { - "type": "error", - "name": "NonZeroContractVersionOnInit", - "inputs": [] - }, - { - "type": "error", - "name": "NotAllowedToRecover", - "inputs": [] - }, - { - "type": "error", - "name": "NotInitializing", - "inputs": [] - }, - { - "type": "error", - "name": "PauseUntilMustBeInFuture", - "inputs": [] - }, - { - "type": "error", - "name": "PausedExpected", - "inputs": [] - }, - { - "type": "error", - "name": "ProcessingDeadlineMissed", - "inputs": [ - { - "name": "deadline", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "RefSlotAlreadyProcessing", - "inputs": [] - }, - { - "type": "error", - "name": "RefSlotCannotDecrease", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "prevRefSlot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "RefSlotMustBeGreaterThanProcessingOne", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "processingRefSlot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "ResumedExpected", - "inputs": [] - }, - { - "type": "error", - "name": "SafeCastOverflowedUintDowncast", - "inputs": [ - { - "name": "bits", - "type": "uint8", - "internalType": "uint8" - }, - { - "name": "value", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "SecondsPerSlotCannotBeZero", - "inputs": [] - }, - { - "type": "error", - "name": "SenderIsNotTheConsensusContract", - "inputs": [] - }, - { - "type": "error", - "name": "SenderNotAllowed", - "inputs": [] - }, - { - "type": "error", - "name": "UnexpectedChainConfig", - "inputs": [] - }, - { - "type": "error", - "name": "UnexpectedConsensusVersion", - "inputs": [ - { - "name": "expectedVersion", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "receivedVersion", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "UnexpectedContractVersion", - "inputs": [ - { - "name": "expected", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "received", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "UnexpectedDataHash", - "inputs": [ - { - "name": "consensusHash", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "receivedHash", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "type": "error", - "name": "UnexpectedRefSlot", - "inputs": [ - { - "name": "consensusRefSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "dataRefSlot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "VersionCannotBeSame", - "inputs": [] - }, - { - "type": "error", - "name": "ZeroPauseDuration", - "inputs": [] - } -] \ No newline at end of file + { + "type": "constructor", + "inputs": [ + { + "name": "secondsPerSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "genesisTime", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "CONTRACT_MANAGER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GENESIS_TIME", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_CONSENSUS_CONTRACT_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_CONSENSUS_VERSION_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_INFINITELY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RECOVERER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RESUME_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SECONDS_PER_SLOT", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SUBMIT_DATA_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "avgPerfLeewayBP", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "discardConsensusReport", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "feeDistributor", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSFeeDistributor" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getConsensusContract", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getConsensusReport", + "inputs": [], + "outputs": [ + { + "name": "hash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "processingDeadlineTime", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "processingStarted", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getConsensusVersion", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getContractVersion", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLastProcessingRefSlot", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getResumeSinceTimestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "admin", + "type": "address", + "internalType": "address" + }, + { + "name": "feeDistributorContract", + "type": "address", + "internalType": "address" + }, + { + "name": "consensusContract", + "type": "address", + "internalType": "address" + }, + { + "name": "consensusVersion", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_avgPerfLeewayBP", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isPaused", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "pauseFor", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pauseUntil", + "inputs": [ + { + "name": "pauseUntilInclusive", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC1155", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC20", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC721", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverEther", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resume", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setConsensusContract", + "inputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setConsensusVersion", + "inputs": [ + { + "name": "version", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setFeeDistributorContract", + "inputs": [ + { + "name": "feeDistributorContract", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setPerformanceLeeway", + "inputs": [ + { + "name": "valueBP", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "submitConsensusReport", + "inputs": [ + { + "name": "reportHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "submitReportData", + "inputs": [ + { + "name": "data", + "type": "tuple", + "internalType": "struct CSFeeOracle.ReportData", + "components": [ + { + "name": "consensusVersion", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "treeRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "treeCid", + "type": "string", + "internalType": "string" + }, + { + "name": "distributed", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "name": "contractVersion", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "ConsensusHashContractSet", + "inputs": [ + { + "name": "addr", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "prevAddr", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ConsensusVersionSet", + "inputs": [ + { + "name": "version", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "prevVersion", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ContractVersionSet", + "inputs": [ + { + "name": "version", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC1155Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC20Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC721Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EtherRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeeDistributorContractSet", + "inputs": [ + { + "name": "feeDistributorContract", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PerfLeewaySet", + "inputs": [ + { + "name": "valueBP", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ProcessingStarted", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "hash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReportDiscarded", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "hash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReportSettled", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "distributed", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "treeRoot", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "treeCid", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReportSubmitted", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "hash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "processingDeadlineTime", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Resumed", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StETHSharesRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WarnProcessingMissed", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "AddressCannotBeSame", + "inputs": [] + }, + { + "type": "error", + "name": "AddressCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "FailedToSendEther", + "inputs": [] + }, + { + "type": "error", + "name": "HashCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "InitialRefSlotCannotBeLessThanProcessingOne", + "inputs": [ + { + "name": "initialRefSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "processingRefSlot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidContractVersionIncrement", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidPerfLeeway", + "inputs": [] + }, + { + "type": "error", + "name": "NoConsensusReportToProcess", + "inputs": [] + }, + { + "type": "error", + "name": "NonZeroContractVersionOnInit", + "inputs": [] + }, + { + "type": "error", + "name": "NotAllowedToRecover", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "PauseUntilMustBeInFuture", + "inputs": [] + }, + { + "type": "error", + "name": "PausedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "ProcessingDeadlineMissed", + "inputs": [ + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "RefSlotAlreadyProcessing", + "inputs": [] + }, + { + "type": "error", + "name": "RefSlotCannotDecrease", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "prevRefSlot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "RefSlotMustBeGreaterThanProcessingOne", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "processingRefSlot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ResumedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "SafeCastOverflowedUintDowncast", + "inputs": [ + { + "name": "bits", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "SecondsPerSlotCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "SenderIsNotTheConsensusContract", + "inputs": [] + }, + { + "type": "error", + "name": "SenderNotAllowed", + "inputs": [] + }, + { + "type": "error", + "name": "UnexpectedChainConfig", + "inputs": [] + }, + { + "type": "error", + "name": "UnexpectedConsensusVersion", + "inputs": [ + { + "name": "expectedVersion", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "receivedVersion", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "UnexpectedContractVersion", + "inputs": [ + { + "name": "expected", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "UnexpectedDataHash", + "inputs": [ + { + "name": "consensusHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "receivedHash", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "UnexpectedRefSlot", + "inputs": [ + { + "name": "consensusRefSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "dataRefSlot", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "VersionCannotBeSame", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAdminAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroFeeDistributorAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroPauseDuration", + "inputs": [] + } + ] diff --git a/interfaces/csm/CSHashConsensus.json b/interfaces/csm/CSHashConsensus.json index 700bf2344..afa2ea3cf 100644 --- a/interfaces/csm/CSHashConsensus.json +++ b/interfaces/csm/CSHashConsensus.json @@ -1,777 +1,1141 @@ [ - { - "inputs": [ - { "internalType": "uint256", "name": "slotsPerEpoch", "type": "uint256" }, - { - "internalType": "uint256", - "name": "secondsPerSlot", - "type": "uint256" - }, - { "internalType": "uint256", "name": "genesisTime", "type": "uint256" }, - { - "internalType": "uint256", - "name": "epochsPerFrame", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fastLaneLengthSlots", - "type": "uint256" - }, - { "internalType": "address", "name": "admin", "type": "address" }, - { - "internalType": "address", - "name": "reportProcessor", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" }, - { - "inputs": [ - { "internalType": "address", "name": "account", "type": "address" }, - { "internalType": "bytes32", "name": "neededRole", "type": "bytes32" } - ], - "name": "AccessControlUnauthorizedAccount", - "type": "error" - }, - { "inputs": [], "name": "AddressCannotBeZero", "type": "error" }, - { "inputs": [], "name": "AdminCannotBeZero", "type": "error" }, - { "inputs": [], "name": "ConsensusReportAlreadyProcessing", "type": "error" }, - { "inputs": [], "name": "DuplicateMember", "type": "error" }, - { "inputs": [], "name": "DuplicateReport", "type": "error" }, - { "inputs": [], "name": "EmptyReport", "type": "error" }, - { "inputs": [], "name": "EpochsPerFrameCannotBeZero", "type": "error" }, - { - "inputs": [], - "name": "FastLanePeriodCannotBeLongerThanFrame", - "type": "error" - }, - { "inputs": [], "name": "InitialEpochAlreadyArrived", "type": "error" }, - { "inputs": [], "name": "InitialEpochIsYetToArrive", "type": "error" }, - { - "inputs": [], - "name": "InitialEpochRefSlotCannotBeEarlierThanProcessingSlot", - "type": "error" - }, - { "inputs": [], "name": "InvalidChainConfig", "type": "error" }, - { "inputs": [], "name": "InvalidInitialization", "type": "error" }, - { "inputs": [], "name": "InvalidSlot", "type": "error" }, - { "inputs": [], "name": "NewProcessorCannotBeTheSame", "type": "error" }, - { - "inputs": [], - "name": "NonFastLaneMemberCannotReportWithinFastLaneInterval", - "type": "error" - }, - { "inputs": [], "name": "NonMember", "type": "error" }, - { "inputs": [], "name": "NotInitializing", "type": "error" }, - { "inputs": [], "name": "NumericOverflow", "type": "error" }, - { - "inputs": [ - { "internalType": "uint256", "name": "minQuorum", "type": "uint256" }, - { "internalType": "uint256", "name": "receivedQuorum", "type": "uint256" } - ], - "name": "QuorumTooSmall", - "type": "error" - }, - { "inputs": [], "name": "ReportProcessorCannotBeZero", "type": "error" }, - { - "inputs": [ - { "internalType": "uint8", "name": "bits", "type": "uint8" }, - { "internalType": "uint256", "name": "value", "type": "uint256" } - ], - "name": "SafeCastOverflowedUintDowncast", - "type": "error" - }, - { "inputs": [], "name": "StaleReport", "type": "error" }, - { - "inputs": [ - { "internalType": "uint256", "name": "expected", "type": "uint256" }, - { "internalType": "uint256", "name": "received", "type": "uint256" } - ], - "name": "UnexpectedConsensusVersion", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - } - ], - "name": "ConsensusLost", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "report", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "support", - "type": "uint256" - } - ], - "name": "ConsensusReached", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "fastLaneLengthSlots", - "type": "uint256" - } - ], - "name": "FastLaneConfigSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "newInitialEpoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newEpochsPerFrame", - "type": "uint256" - } - ], - "name": "FrameConfigSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "version", - "type": "uint64" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newTotalMembers", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newQuorum", - "type": "uint256" - } - ], - "name": "MemberAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newTotalMembers", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newQuorum", - "type": "uint256" - } - ], - "name": "MemberRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "newQuorum", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "totalMembers", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "prevQuorum", - "type": "uint256" - } - ], - "name": "QuorumSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "processor", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "prevProcessor", - "type": "address" - } - ], - "name": "ReportProcessorSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "refSlot", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "member", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "report", - "type": "bytes32" - } - ], - "name": "ReportReceived", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "DISABLE_CONSENSUS_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MANAGE_FAST_LANE_CONFIG_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MANAGE_FRAME_CONFIG_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MANAGE_MEMBERS_AND_QUORUM_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MANAGE_REPORT_PROCESSOR_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" }, - { "internalType": "uint256", "name": "quorum", "type": "uint256" } - ], - "name": "addMember", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "disableConsensus", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getChainConfig", - "outputs": [ - { "internalType": "uint256", "name": "slotsPerEpoch", "type": "uint256" }, - { - "internalType": "uint256", - "name": "secondsPerSlot", - "type": "uint256" - }, - { "internalType": "uint256", "name": "genesisTime", "type": "uint256" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getConsensusState", - "outputs": [ - { "internalType": "uint256", "name": "refSlot", "type": "uint256" }, - { - "internalType": "bytes32", - "name": "consensusReport", - "type": "bytes32" - }, - { "internalType": "bool", "name": "isReportProcessing", "type": "bool" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" } - ], - "name": "getConsensusStateForMember", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "currentFrameRefSlot", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "currentFrameConsensusReport", - "type": "bytes32" - }, - { "internalType": "bool", "name": "isMember", "type": "bool" }, - { "internalType": "bool", "name": "isFastLane", "type": "bool" }, - { "internalType": "bool", "name": "canReport", "type": "bool" }, - { - "internalType": "uint256", - "name": "lastMemberReportRefSlot", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "currentFrameMemberReport", - "type": "bytes32" - } - ], - "internalType": "struct HashConsensus.MemberConsensusState", - "name": "result", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentFrame", - "outputs": [ - { "internalType": "uint256", "name": "refSlot", "type": "uint256" }, - { - "internalType": "uint256", - "name": "reportProcessingDeadlineSlot", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getFastLaneMembers", - "outputs": [ - { "internalType": "address[]", "name": "addresses", "type": "address[]" }, - { - "internalType": "uint256[]", - "name": "lastReportedRefSlots", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getFrameConfig", - "outputs": [ - { "internalType": "uint256", "name": "initialEpoch", "type": "uint256" }, - { - "internalType": "uint256", - "name": "epochsPerFrame", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fastLaneLengthSlots", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getInitialRefSlot", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" } - ], - "name": "getIsFastLaneMember", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" } - ], - "name": "getIsMember", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getMembers", - "outputs": [ - { "internalType": "address[]", "name": "addresses", "type": "address[]" }, - { - "internalType": "uint256[]", - "name": "lastReportedRefSlots", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getQuorum", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getReportProcessor", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getReportVariants", - "outputs": [ - { "internalType": "bytes32[]", "name": "variants", "type": "bytes32[]" }, - { "internalType": "uint256[]", "name": "support", "type": "uint256[]" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" } - ], - "name": "getRoleAdmin", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { "internalType": "uint256", "name": "index", "type": "uint256" } - ], - "name": "getRoleMember", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" } - ], - "name": "getRoleMemberCount", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { "internalType": "address", "name": "account", "type": "address" } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { "internalType": "address", "name": "account", "type": "address" } - ], - "name": "hasRole", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "addr", "type": "address" }, - { "internalType": "uint256", "name": "quorum", "type": "uint256" } - ], - "name": "removeMember", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { - "internalType": "address", - "name": "callerConfirmation", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { "internalType": "address", "name": "account", "type": "address" } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "fastLaneLengthSlots", - "type": "uint256" - } - ], - "name": "setFastLaneLengthSlots", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "epochsPerFrame", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fastLaneLengthSlots", - "type": "uint256" - } - ], - "name": "setFrameConfig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "quorum", "type": "uint256" } - ], - "name": "setQuorum", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "newProcessor", "type": "address" } - ], - "name": "setReportProcessor", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "slot", "type": "uint256" }, - { "internalType": "bytes32", "name": "report", "type": "bytes32" }, - { - "internalType": "uint256", - "name": "consensusVersion", - "type": "uint256" - } - ], - "name": "submitReport", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } - ], - "name": "supportsInterface", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "initialEpoch", "type": "uint256" } - ], - "name": "updateInitialEpoch", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] + { + "type": "constructor", + "inputs": [ + { + "name": "slotsPerEpoch", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "secondsPerSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "genesisTime", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "epochsPerFrame", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "fastLaneLengthSlots", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "admin", + "type": "address", + "internalType": "address" + }, + { + "name": "reportProcessor", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DISABLE_CONSENSUS_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_FAST_LANE_CONFIG_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_FRAME_CONFIG_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_MEMBERS_AND_QUORUM_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MANAGE_REPORT_PROCESSOR_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addMember", + "inputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + }, + { + "name": "quorum", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "disableConsensus", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getChainConfig", + "inputs": [], + "outputs": [ + { + "name": "slotsPerEpoch", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "secondsPerSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "genesisTime", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getConsensusState", + "inputs": [], + "outputs": [ + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "consensusReport", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "isReportProcessing", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getConsensusStateForMember", + "inputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "result", + "type": "tuple", + "internalType": "struct HashConsensus.MemberConsensusState", + "components": [ + { + "name": "currentFrameRefSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "currentFrameConsensusReport", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "isMember", + "type": "bool", + "internalType": "bool" + }, + { + "name": "isFastLane", + "type": "bool", + "internalType": "bool" + }, + { + "name": "canReport", + "type": "bool", + "internalType": "bool" + }, + { + "name": "lastMemberReportRefSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "currentFrameMemberReport", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getCurrentFrame", + "inputs": [], + "outputs": [ + { + "name": "refSlot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "reportProcessingDeadlineSlot", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getFastLaneMembers", + "inputs": [], + "outputs": [ + { + "name": "addresses", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "lastReportedRefSlots", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getFrameConfig", + "inputs": [], + "outputs": [ + { + "name": "initialEpoch", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "epochsPerFrame", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "fastLaneLengthSlots", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getInitialRefSlot", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getIsFastLaneMember", + "inputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getIsMember", + "inputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getMembers", + "inputs": [], + "outputs": [ + { + "name": "addresses", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "lastReportedRefSlots", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getQuorum", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getReportProcessor", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getReportVariants", + "inputs": [], + "outputs": [ + { + "name": "variants", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "support", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "removeMember", + "inputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + }, + { + "name": "quorum", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setFastLaneLengthSlots", + "inputs": [ + { + "name": "fastLaneLengthSlots", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setFrameConfig", + "inputs": [ + { + "name": "epochsPerFrame", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "fastLaneLengthSlots", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setQuorum", + "inputs": [ + { + "name": "quorum", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setReportProcessor", + "inputs": [ + { + "name": "newProcessor", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "submitReport", + "inputs": [ + { + "name": "slot", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "report", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "consensusVersion", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "updateInitialEpoch", + "inputs": [ + { + "name": "initialEpoch", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "ConsensusLost", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ConsensusReached", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "report", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "support", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FastLaneConfigSet", + "inputs": [ + { + "name": "fastLaneLengthSlots", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FrameConfigSet", + "inputs": [ + { + "name": "newInitialEpoch", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newEpochsPerFrame", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MemberAdded", + "inputs": [ + { + "name": "addr", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newTotalMembers", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newQuorum", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MemberRemoved", + "inputs": [ + { + "name": "addr", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newTotalMembers", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newQuorum", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "QuorumSet", + "inputs": [ + { + "name": "newQuorum", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "totalMembers", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "prevQuorum", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReportProcessorSet", + "inputs": [ + { + "name": "processor", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "prevProcessor", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReportReceived", + "inputs": [ + { + "name": "refSlot", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "member", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "report", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "AddressCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "AdminCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "ConsensusReportAlreadyProcessing", + "inputs": [] + }, + { + "type": "error", + "name": "DuplicateMember", + "inputs": [] + }, + { + "type": "error", + "name": "DuplicateReport", + "inputs": [] + }, + { + "type": "error", + "name": "EmptyReport", + "inputs": [] + }, + { + "type": "error", + "name": "EpochsPerFrameCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "FastLanePeriodCannotBeLongerThanFrame", + "inputs": [] + }, + { + "type": "error", + "name": "InitialEpochAlreadyArrived", + "inputs": [] + }, + { + "type": "error", + "name": "InitialEpochIsYetToArrive", + "inputs": [] + }, + { + "type": "error", + "name": "InitialEpochRefSlotCannotBeEarlierThanProcessingSlot", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidChainConfig", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidSlot", + "inputs": [] + }, + { + "type": "error", + "name": "NewProcessorCannotBeTheSame", + "inputs": [] + }, + { + "type": "error", + "name": "NonFastLaneMemberCannotReportWithinFastLaneInterval", + "inputs": [] + }, + { + "type": "error", + "name": "NonMember", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "NumericOverflow", + "inputs": [] + }, + { + "type": "error", + "name": "QuorumTooSmall", + "inputs": [ + { + "name": "minQuorum", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "receivedQuorum", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ReportProcessorCannotBeZero", + "inputs": [] + }, + { + "type": "error", + "name": "SafeCastOverflowedUintDowncast", + "inputs": [ + { + "name": "bits", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "StaleReport", + "inputs": [] + }, + { + "type": "error", + "name": "UnexpectedConsensusVersion", + "inputs": [ + { + "name": "expected", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "received", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] diff --git a/interfaces/csm/CSModule.json b/interfaces/csm/CSModule.json index c5bf6e454..d2a5e9255 100644 --- a/interfaces/csm/CSModule.json +++ b/interfaces/csm/CSModule.json @@ -1,1793 +1,2986 @@ [ - { - "inputs": [ - { "internalType": "bytes32", "name": "moduleType", "type": "bytes32" }, - { - "internalType": "uint256", - "name": "minSlashingPenaltyQuotient", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "elRewardsStealingFine", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxKeysPerOperatorEA", - "type": "uint256" - }, - { "internalType": "address", "name": "lidoLocator", "type": "address" } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" }, - { - "inputs": [ - { "internalType": "address", "name": "account", "type": "address" }, - { "internalType": "bytes32", "name": "neededRole", "type": "bytes32" } - ], - "name": "AccessControlUnauthorizedAccount", - "type": "error" - }, - { "inputs": [], "name": "AlreadyActivated", "type": "error" }, - { "inputs": [], "name": "AlreadySubmitted", "type": "error" }, - { "inputs": [], "name": "AlreadyWithdrawn", "type": "error" }, - { "inputs": [], "name": "EmptyKey", "type": "error" }, - { "inputs": [], "name": "ExitedKeysDecrease", "type": "error" }, - { - "inputs": [], - "name": "ExitedKeysHigherThanTotalDeposited", - "type": "error" - }, - { "inputs": [], "name": "InvalidAmount", "type": "error" }, - { "inputs": [], "name": "InvalidInitialization", "type": "error" }, - { "inputs": [], "name": "InvalidInput", "type": "error" }, - { "inputs": [], "name": "InvalidKeysCount", "type": "error" }, - { "inputs": [], "name": "InvalidLength", "type": "error" }, - { "inputs": [], "name": "InvalidReportData", "type": "error" }, - { "inputs": [], "name": "InvalidVetKeysPointer", "type": "error" }, - { "inputs": [], "name": "MaxSigningKeysCountExceeded", "type": "error" }, - { "inputs": [], "name": "NodeOperatorDoesNotExist", "type": "error" }, - { "inputs": [], "name": "NotAllowedToJoinYet", "type": "error" }, - { "inputs": [], "name": "NotAllowedToRecover", "type": "error" }, - { "inputs": [], "name": "NotEnoughKeys", "type": "error" }, - { "inputs": [], "name": "NotInitializing", "type": "error" }, - { "inputs": [], "name": "NotSupported", "type": "error" }, - { "inputs": [], "name": "PauseUntilMustBeInFuture", "type": "error" }, - { "inputs": [], "name": "PausedExpected", "type": "error" }, - { "inputs": [], "name": "QueueIsEmpty", "type": "error" }, - { "inputs": [], "name": "ResumedExpected", "type": "error" }, - { "inputs": [], "name": "SenderIsNotEligible", "type": "error" }, - { "inputs": [], "name": "SigningKeysInvalidOffset", "type": "error" }, - { "inputs": [], "name": "StuckKeysHigherThanNonExited", "type": "error" }, - { "inputs": [], "name": "ZeroAccountingAddress", "type": "error" }, - { "inputs": [], "name": "ZeroAdminAddress", "type": "error" }, - { "inputs": [], "name": "ZeroLocatorAddress", "type": "error" }, - { "inputs": [], "name": "ZeroPauseDuration", "type": "error" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "depositedKeysCount", - "type": "uint256" - } - ], - "name": "DepositedSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ELRewardsStealingPenaltyCancelled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "proposedBlockHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "stolenAmount", - "type": "uint256" - } - ], - "name": "ELRewardsStealingPenaltyReported", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - } - ], - "name": "ELRewardsStealingPenaltySettled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "exitedKeysCount", - "type": "uint256" - } - ], - "name": "ExitedSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "keyIndex", - "type": "uint256" - } - ], - "name": "InitialSlashingSubmitted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "version", - "type": "uint64" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "KeyRemovalChargeApplied", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "KeyRemovalChargeSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "managerAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "rewardAddress", - "type": "address" - } - ], - "name": "NodeOperatorAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - } - ], - "name": "NonceChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "duration", - "type": "uint256" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [], - "name": "PublicRelease", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "referrer", - "type": "address" - } - ], - "name": "ReferrerSet", - "type": "event" - }, - { "anonymous": false, "inputs": [], "name": "Resumed", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "pubkey", - "type": "bytes" - } - ], - "name": "SigningKeyAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "pubkey", - "type": "bytes" - } - ], - "name": "SigningKeyAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "pubkey", - "type": "bytes" - } - ], - "name": "SigningKeyRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "pubkey", - "type": "bytes" - } - ], - "name": "SigningKeyRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "stuckKeysCount", - "type": "uint256" - } - ], - "name": "StuckSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "targetLimitMode", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "targetValidatorsCount", - "type": "uint256" - } - ], - "name": "TargetValidatorsCountChangedByRequest", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "totalKeysCount", - "type": "uint256" - } - ], - "name": "TotalSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "vettedKeysCount", - "type": "uint256" - } - ], - "name": "VettedSigningKeysCountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "keyIndex", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrawalSubmitted", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "EL_REWARDS_STEALING_FINE", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIAL_SLASHING_PENALTY", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "LIDO_LOCATOR", - "outputs": [ - { "internalType": "contract ILidoLocator", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MAX_SIGNING_KEYS_PER_OPERATOR_BEFORE_PUBLIC_RELEASE", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MODULE_MANAGER_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PAUSE_INFINITELY", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PAUSE_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RECOVERER_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "REPORT_EL_REWARDS_STEALING_PENALTY_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RESUME_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "STAKING_ROUTER_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "STETH", - "outputs": [ - { "internalType": "contract IStETH", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERIFIER_ROLE", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "accounting", - "outputs": [ - { - "internalType": "contract ICSAccounting", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "activatePublicRelease", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, - { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, - { "internalType": "bytes", "name": "signatures", "type": "bytes" }, - { - "internalType": "address", - "name": "managerAddress", - "type": "address" - }, - { "internalType": "address", "name": "rewardAddress", "type": "address" }, - { "internalType": "bytes32[]", "name": "eaProof", "type": "bytes32[]" }, - { "internalType": "address", "name": "referrer", "type": "address" } - ], - "name": "addNodeOperatorETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, - { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, - { "internalType": "bytes", "name": "signatures", "type": "bytes" }, - { - "internalType": "address", - "name": "managerAddress", - "type": "address" - }, - { "internalType": "address", "name": "rewardAddress", "type": "address" }, - { - "components": [ - { "internalType": "uint256", "name": "value", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "internalType": "struct ICSAccounting.PermitInput", - "name": "permit", - "type": "tuple" - }, - { "internalType": "bytes32[]", "name": "eaProof", "type": "bytes32[]" }, - { "internalType": "address", "name": "referrer", "type": "address" } - ], - "name": "addNodeOperatorStETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, - { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, - { "internalType": "bytes", "name": "signatures", "type": "bytes" }, - { - "internalType": "address", - "name": "managerAddress", - "type": "address" - }, - { "internalType": "address", "name": "rewardAddress", "type": "address" }, - { - "components": [ - { "internalType": "uint256", "name": "value", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "internalType": "struct ICSAccounting.PermitInput", - "name": "permit", - "type": "tuple" - }, - { "internalType": "bytes32[]", "name": "eaProof", "type": "bytes32[]" }, - { "internalType": "address", "name": "referrer", "type": "address" } - ], - "name": "addNodeOperatorWstETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, - { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, - { "internalType": "bytes", "name": "signatures", "type": "bytes" } - ], - "name": "addValidatorKeysETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, - { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, - { "internalType": "bytes", "name": "signatures", "type": "bytes" }, - { - "components": [ - { "internalType": "uint256", "name": "value", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "internalType": "struct ICSAccounting.PermitInput", - "name": "permit", - "type": "tuple" - } - ], - "name": "addValidatorKeysStETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "keysCount", "type": "uint256" }, - { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, - { "internalType": "bytes", "name": "signatures", "type": "bytes" }, - { - "components": [ - { "internalType": "uint256", "name": "value", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "internalType": "struct ICSAccounting.PermitInput", - "name": "permit", - "type": "tuple" - } - ], - "name": "addValidatorKeysWstETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "cancelELRewardsStealingPenalty", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "stETHAmount", "type": "uint256" }, - { - "internalType": "uint256", - "name": "cumulativeFeeShares", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "rewardsProof", - "type": "bytes32[]" - } - ], - "name": "claimRewardsStETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "stEthAmount", "type": "uint256" }, - { - "internalType": "uint256", - "name": "cumulativeFeeShares", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "rewardsProof", - "type": "bytes32[]" - } - ], - "name": "claimRewardsUnstETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "wstETHAmount", "type": "uint256" }, - { - "internalType": "uint256", - "name": "cumulativeFeeShares", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "rewardsProof", - "type": "bytes32[]" - } - ], - "name": "claimRewardsWstETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "maxItems", "type": "uint256" } - ], - "name": "cleanDepositQueue", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "compensateELRewardsStealingPenalty", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "confirmNodeOperatorManagerAddressChange", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "confirmNodeOperatorRewardAddressChange", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes", "name": "nodeOperatorIds", "type": "bytes" }, - { - "internalType": "bytes", - "name": "vettedSigningKeysCounts", - "type": "bytes" - } - ], - "name": "decreaseVettedSigningKeysCount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "depositETH", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "depositQueue", - "outputs": [ - { "internalType": "uint128", "name": "head", "type": "uint128" }, - { "internalType": "uint128", "name": "length", "type": "uint128" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint128", "name": "index", "type": "uint128" } - ], - "name": "depositQueueItem", - "outputs": [{ "internalType": "Batch", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "stETHAmount", "type": "uint256" }, - { - "components": [ - { "internalType": "uint256", "name": "value", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "internalType": "struct ICSAccounting.PermitInput", - "name": "permit", - "type": "tuple" - } - ], - "name": "depositStETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "wstETHAmount", "type": "uint256" }, - { - "components": [ - { "internalType": "uint256", "name": "value", "type": "uint256" }, - { "internalType": "uint256", "name": "deadline", "type": "uint256" }, - { "internalType": "uint8", "name": "v", "type": "uint8" }, - { "internalType": "bytes32", "name": "r", "type": "bytes32" }, - { "internalType": "bytes32", "name": "s", "type": "bytes32" } - ], - "internalType": "struct ICSAccounting.PermitInput", - "name": "permit", - "type": "tuple" - } - ], - "name": "depositWstETH", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "earlyAdoption", - "outputs": [ - { - "internalType": "contract ICSEarlyAdoption", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getActiveNodeOperatorsCount", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "getNodeOperator", - "outputs": [ - { - "components": [ - { - "internalType": "uint32", - "name": "totalAddedKeys", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "totalWithdrawnKeys", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "totalDepositedKeys", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "totalVettedKeys", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "stuckValidatorsCount", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "depositableValidatorsCount", - "type": "uint32" - }, - { "internalType": "uint32", "name": "targetLimit", "type": "uint32" }, - { - "internalType": "uint8", - "name": "targetLimitMode", - "type": "uint8" - }, - { - "internalType": "uint32", - "name": "totalExitedKeys", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "enqueuedCount", - "type": "uint32" - }, - { - "internalType": "address", - "name": "managerAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "proposedManagerAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "rewardAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "proposedRewardAddress", - "type": "address" - } - ], - "internalType": "struct NodeOperator", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "offset", "type": "uint256" }, - { "internalType": "uint256", "name": "limit", "type": "uint256" } - ], - "name": "getNodeOperatorIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "nodeOperatorIds", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "getNodeOperatorIsActive", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "getNodeOperatorNonWithdrawnKeys", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "getNodeOperatorSummary", - "outputs": [ - { - "internalType": "uint256", - "name": "targetLimitMode", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "targetValidatorsCount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "stuckValidatorsCount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "refundedValidatorsCount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "stuckPenaltyEndTimestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "totalExitedValidators", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "totalDepositedValidators", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "depositableValidatorsCount", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNodeOperatorsCount", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNonce", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getResumeSinceTimestamp", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" } - ], - "name": "getRoleAdmin", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { "internalType": "uint256", "name": "index", "type": "uint256" } - ], - "name": "getRoleMember", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" } - ], - "name": "getRoleMemberCount", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "startIndex", "type": "uint256" }, - { "internalType": "uint256", "name": "keysCount", "type": "uint256" } - ], - "name": "getSigningKeys", - "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "startIndex", "type": "uint256" }, - { "internalType": "uint256", "name": "keysCount", "type": "uint256" } - ], - "name": "getSigningKeysWithSignatures", - "outputs": [ - { "internalType": "bytes", "name": "keys", "type": "bytes" }, - { "internalType": "bytes", "name": "signatures", "type": "bytes" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getStakingModuleSummary", - "outputs": [ - { - "internalType": "uint256", - "name": "totalExitedValidators", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "totalDepositedValidators", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "depositableValidatorsCount", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getType", - "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { "internalType": "address", "name": "account", "type": "address" } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { "internalType": "address", "name": "account", "type": "address" } - ], - "name": "hasRole", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_accounting", "type": "address" }, - { - "internalType": "address", - "name": "_earlyAdoption", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_keyRemovalCharge", - "type": "uint256" - }, - { "internalType": "address", "name": "admin", "type": "address" } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "isPaused", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "keyIndex", "type": "uint256" } - ], - "name": "isValidatorSlashed", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "keyIndex", "type": "uint256" } - ], - "name": "isValidatorWithdrawn", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "keyRemovalCharge", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "normalizeQueue", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "depositsCount", "type": "uint256" }, - { "internalType": "bytes", "name": "", "type": "bytes" } - ], - "name": "obtainDepositData", - "outputs": [ - { "internalType": "bytes", "name": "publicKeys", "type": "bytes" }, - { "internalType": "bytes", "name": "signatures", "type": "bytes" } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "onExitedAndStuckValidatorsCountsUpdated", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "totalShares", "type": "uint256" } - ], - "name": "onRewardsMinted", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "onWithdrawalCredentialsChanged", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "duration", "type": "uint256" } - ], - "name": "pauseFor", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "proposedAddress", - "type": "address" - } - ], - "name": "proposeNodeOperatorManagerAddressChange", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "proposedAddress", - "type": "address" - } - ], - "name": "proposeNodeOperatorRewardAddressChange", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "publicRelease", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "recoverERC1155", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "recoverERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "token", "type": "address" }, - { "internalType": "uint256", "name": "tokenId", "type": "uint256" } - ], - "name": "recoverERC721", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "recoverEther", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "recoverStETHShares", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "startIndex", "type": "uint256" }, - { "internalType": "uint256", "name": "keysCount", "type": "uint256" } - ], - "name": "removeKeys", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { - "internalType": "address", - "name": "callerConfirmation", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "reportELRewardsStealingPenalty", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "nodeOperatorId", "type": "uint256" } - ], - "name": "resetNodeOperatorManagerAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "resume", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "role", "type": "bytes32" }, - { "internalType": "address", "name": "account", "type": "address" } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "setKeyRemovalCharge", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256[]", - "name": "nodeOperatorIds", - "type": "uint256[]" - } - ], - "name": "settleELRewardsStealingPenalty", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "keyIndex", "type": "uint256" } - ], - "name": "submitInitialSlashing", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { "internalType": "uint256", "name": "keyIndex", "type": "uint256" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "submitWithdrawal", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } - ], - "name": "supportsInterface", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "exitedValidatorsKeysCount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "stuckValidatorsKeysCount", - "type": "uint256" - } - ], - "name": "unsafeUpdateValidatorsCount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes", "name": "nodeOperatorIds", "type": "bytes" }, - { - "internalType": "bytes", - "name": "exitedValidatorsCounts", - "type": "bytes" - } - ], - "name": "updateExitedValidatorsCount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "uint256", "name": "", "type": "uint256" } - ], - "name": "updateRefundedValidatorsCount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes", "name": "nodeOperatorIds", "type": "bytes" }, - { - "internalType": "bytes", - "name": "stuckValidatorsCounts", - "type": "bytes" - } - ], - "name": "updateStuckValidatorsCount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "nodeOperatorId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "targetLimitMode", - "type": "uint256" - }, - { "internalType": "uint256", "name": "targetLimit", "type": "uint256" } - ], - "name": "updateTargetValidatorsLimits", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] + { + "type": "constructor", + "inputs": [ + { + "name": "moduleType", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "minSlashingPenaltyQuotient", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "elRewardsStealingFine", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxKeysPerOperatorEA", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "lidoLocator", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "EL_REWARDS_STEALING_FINE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "INITIAL_SLASHING_PENALTY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "LIDO_LOCATOR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ILidoLocator" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MAX_SIGNING_KEYS_PER_OPERATOR_BEFORE_PUBLIC_RELEASE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MODULE_MANAGER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_INFINITELY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PAUSE_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RECOVERER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "REPORT_EL_REWARDS_STEALING_PENALTY_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "RESUME_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "STAKING_ROUTER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "STETH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IStETH" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "VERIFIER_ROLE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "accounting", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSAccounting" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "activatePublicRelease", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "addNodeOperatorETH", + "inputs": [ + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "publicKeys", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signatures", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "managementProperties", + "type": "tuple", + "internalType": "struct NodeOperatorManagementProperties", + "components": [ + { + "name": "managerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "extendedManagerPermissions", + "type": "bool", + "internalType": "bool" + } + ] + }, + { + "name": "eaProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "referrer", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "addNodeOperatorStETH", + "inputs": [ + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "publicKeys", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signatures", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "managementProperties", + "type": "tuple", + "internalType": "struct NodeOperatorManagementProperties", + "components": [ + { + "name": "managerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "extendedManagerPermissions", + "type": "bool", + "internalType": "bool" + } + ] + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct ICSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "eaProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "referrer", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "addNodeOperatorWstETH", + "inputs": [ + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "publicKeys", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signatures", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "managementProperties", + "type": "tuple", + "internalType": "struct NodeOperatorManagementProperties", + "components": [ + { + "name": "managerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "extendedManagerPermissions", + "type": "bool", + "internalType": "bool" + } + ] + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct ICSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "eaProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "referrer", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "addValidatorKeysETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "publicKeys", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signatures", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "addValidatorKeysStETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "publicKeys", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signatures", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct ICSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "addValidatorKeysWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "publicKeys", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signatures", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct ICSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "cancelELRewardsStealingPenalty", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "changeNodeOperatorRewardAddress", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "newAddress", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewardsStETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewardsUnstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stEthAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewardsWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "wstETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cumulativeFeeShares", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardsProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "cleanDepositQueue", + "inputs": [ + { + "name": "maxItems", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "compensateELRewardsStealingPenalty", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "confirmNodeOperatorManagerAddressChange", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "confirmNodeOperatorRewardAddressChange", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "decreaseVettedSigningKeysCount", + "inputs": [ + { + "name": "nodeOperatorIds", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "vettedSigningKeysCounts", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "depositETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "depositQueue", + "inputs": [], + "outputs": [ + { + "name": "head", + "type": "uint128", + "internalType": "uint128" + }, + { + "name": "tail", + "type": "uint128", + "internalType": "uint128" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "depositQueueItem", + "inputs": [ + { + "name": "index", + "type": "uint128", + "internalType": "uint128" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "Batch" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "depositStETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct ICSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "depositWstETH", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "wstETHAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "permit", + "type": "tuple", + "internalType": "struct ICSAccounting.PermitInput", + "components": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "earlyAdoption", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSEarlyAdoption" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getActiveNodeOperatorsCount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getNodeOperator", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct NodeOperator", + "components": [ + { + "name": "totalAddedKeys", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "totalWithdrawnKeys", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "totalDepositedKeys", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "totalVettedKeys", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "stuckValidatorsCount", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "depositableValidatorsCount", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "targetLimit", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "targetLimitMode", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "totalExitedKeys", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "enqueuedCount", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "managerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "proposedManagerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "proposedRewardAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "extendedManagerPermissions", + "type": "bool", + "internalType": "bool" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getNodeOperatorIds", + "inputs": [ + { + "name": "offset", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "limit", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "nodeOperatorIds", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getNodeOperatorIsActive", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getNodeOperatorNonWithdrawnKeys", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getNodeOperatorSummary", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "targetLimitMode", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "targetValidatorsCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stuckValidatorsCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "refundedValidatorsCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stuckPenaltyEndTimestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalExitedValidators", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getNodeOperatorsCount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getNonce", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getResumeSinceTimestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getSigningKeys", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "startIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getSigningKeysWithSignatures", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "startIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "keys", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signatures", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getStakingModuleSummary", + "inputs": [], + "outputs": [ + { + "name": "totalExitedValidators", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalDepositedValidators", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "depositableValidatorsCount", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getType", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_accounting", + "type": "address", + "internalType": "address" + }, + { + "name": "_earlyAdoption", + "type": "address", + "internalType": "address" + }, + { + "name": "_keyRemovalCharge", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "admin", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isPaused", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isValidatorSlashed", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isValidatorWithdrawn", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "keyRemovalCharge", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "normalizeQueue", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "obtainDepositData", + "inputs": [ + { + "name": "depositsCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "publicKeys", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signatures", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onExitedAndStuckValidatorsCountsUpdated", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onRewardsMinted", + "inputs": [ + { + "name": "totalShares", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onWithdrawalCredentialsChanged", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pauseFor", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "proposeNodeOperatorManagerAddressChange", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "proposedAddress", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "proposeNodeOperatorRewardAddressChange", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "proposedAddress", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "publicRelease", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "recoverERC1155", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC20", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverERC721", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverEther", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "recoverStETHShares", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "removeKeys", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "startIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keysCount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "reportELRewardsStealingPenalty", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "blockHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resetNodeOperatorManagerAddress", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resume", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setKeyRemovalCharge", + "inputs": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "settleELRewardsStealingPenalty", + "inputs": [ + { + "name": "nodeOperatorIds", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "submitInitialSlashing", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "submitWithdrawal", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "isSlashed", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "unsafeUpdateValidatorsCount", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exitedValidatorsKeysCount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stuckValidatorsKeysCount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateExitedValidatorsCount", + "inputs": [ + { + "name": "nodeOperatorIds", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "exitedValidatorsCounts", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateRefundedValidatorsCount", + "inputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateStuckValidatorsCount", + "inputs": [ + { + "name": "nodeOperatorIds", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "stuckValidatorsCounts", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateTargetValidatorsLimits", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "targetLimitMode", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "targetLimit", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "BatchEnqueued", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "count", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DepositableSigningKeysCountChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "depositableKeysCount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DepositedSigningKeysCountChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "depositedKeysCount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ELRewardsStealingPenaltyCancelled", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ELRewardsStealingPenaltyReported", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "proposedBlockHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "stolenAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ELRewardsStealingPenaltySettled", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC1155Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC20Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ERC721Recovered", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EtherRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ExitedSigningKeysCountChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "exitedKeysCount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "InitialSlashingSubmitted", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "KeyRemovalChargeApplied", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "KeyRemovalChargeSet", + "inputs": [ + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NodeOperatorAdded", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "managerAddress", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "rewardAddress", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NodeOperatorManagerAddressChangeProposed", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "oldProposedAddress", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newProposedAddress", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NodeOperatorManagerAddressChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "oldAddress", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newAddress", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NodeOperatorRewardAddressChangeProposed", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "oldProposedAddress", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newProposedAddress", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NodeOperatorRewardAddressChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "oldAddress", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newAddress", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NonceChanged", + "inputs": [ + { + "name": "nonce", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [ + { + "name": "duration", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PublicRelease", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "ReferrerSet", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "referrer", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Resumed", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SigningKeyAdded", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "pubkey", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SigningKeyRemoved", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "pubkey", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StETHSharesRecovered", + "inputs": [ + { + "name": "recipient", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StuckSigningKeysCountChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "stuckKeysCount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TargetValidatorsCountChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "targetLimitMode", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "targetValidatorsCount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TotalSigningKeysCountChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "totalKeysCount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "VettedSigningKeysCountChanged", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "vettedKeysCount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "VettedSigningKeysCountDecreased", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WithdrawalSubmitted", + "inputs": [ + { + "name": "nodeOperatorId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccessControlBadConfirmation", + "inputs": [] + }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "neededRole", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "AlreadyActivated", + "inputs": [] + }, + { + "type": "error", + "name": "AlreadyProposed", + "inputs": [] + }, + { + "type": "error", + "name": "AlreadySubmitted", + "inputs": [] + }, + { + "type": "error", + "name": "AlreadyWithdrawn", + "inputs": [] + }, + { + "type": "error", + "name": "EmptyKey", + "inputs": [] + }, + { + "type": "error", + "name": "ExitedKeysDecrease", + "inputs": [] + }, + { + "type": "error", + "name": "ExitedKeysHigherThanTotalDeposited", + "inputs": [] + }, + { + "type": "error", + "name": "FailedToSendEther", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidAmount", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInput", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidKeysCount", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidLength", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidReportData", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidVetKeysPointer", + "inputs": [] + }, + { + "type": "error", + "name": "MaxSigningKeysCountExceeded", + "inputs": [] + }, + { + "type": "error", + "name": "MethodCallIsNotAllowed", + "inputs": [] + }, + { + "type": "error", + "name": "NodeOperatorDoesNotExist", + "inputs": [] + }, + { + "type": "error", + "name": "NotAllowedToJoinYet", + "inputs": [] + }, + { + "type": "error", + "name": "NotAllowedToRecover", + "inputs": [] + }, + { + "type": "error", + "name": "NotEnoughKeys", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "NotSupported", + "inputs": [] + }, + { + "type": "error", + "name": "PauseUntilMustBeInFuture", + "inputs": [] + }, + { + "type": "error", + "name": "PausedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "QueueIsEmpty", + "inputs": [] + }, + { + "type": "error", + "name": "QueueLookupNoLimit", + "inputs": [] + }, + { + "type": "error", + "name": "ResumedExpected", + "inputs": [] + }, + { + "type": "error", + "name": "SameAddress", + "inputs": [] + }, + { + "type": "error", + "name": "SenderIsNotEligible", + "inputs": [] + }, + { + "type": "error", + "name": "SenderIsNotManagerAddress", + "inputs": [] + }, + { + "type": "error", + "name": "SenderIsNotProposedAddress", + "inputs": [] + }, + { + "type": "error", + "name": "SenderIsNotRewardAddress", + "inputs": [] + }, + { + "type": "error", + "name": "SigningKeysInvalidOffset", + "inputs": [] + }, + { + "type": "error", + "name": "StuckKeysHigherThanNonExited", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAccountingAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroAdminAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroLocatorAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroPauseDuration", + "inputs": [] + } + ] diff --git a/interfaces/csm/CSVerifier.json b/interfaces/csm/CSVerifier.json index d8ce7029d..ec30f8974 100644 --- a/interfaces/csm/CSVerifier.json +++ b/interfaces/csm/CSVerifier.json @@ -1,647 +1,711 @@ [ - { - "type": "constructor", - "inputs": [ - { - "name": "slotsPerEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "gIHistoricalSummaries", - "type": "bytes32", - "internalType": "GIndex" - }, - { - "name": "gIFirstWithdrawal", - "type": "bytes32", - "internalType": "GIndex" - }, - { - "name": "gIFirstValidator", - "type": "bytes32", - "internalType": "GIndex" - }, - { - "name": "firstSupportedSlot", - "type": "uint64", - "internalType": "Slot" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "BEACON_ROOTS", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "FIRST_SUPPORTED_SLOT", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint64", - "internalType": "Slot" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "GI_FIRST_VALIDATOR", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "GIndex" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "GI_FIRST_WITHDRAWAL", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "GIndex" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "GI_HISTORICAL_SUMMARIES", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "GIndex" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "SLOTS_PER_EPOCH", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint64", - "internalType": "uint64" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "initialize", - "inputs": [ - { - "name": "_locator", - "type": "address", - "internalType": "address" - }, - { - "name": "_module", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "locator", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract ILidoLocator" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "module", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract ICSModule" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "processHistoricalWithdrawalProof", - "inputs": [ - { - "name": "beaconBlock", - "type": "tuple", - "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", - "components": [ - { - "name": "header", - "type": "tuple", - "internalType": "struct BeaconBlockHeader", - "components": [ - { - "name": "slot", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "proposerIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "parentRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "stateRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "bodyRoot", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "name": "rootsTimestamp", - "type": "uint64", - "internalType": "uint64" - } - ] - }, - { - "name": "oldBlock", - "type": "tuple", - "internalType": "struct ICSVerifier.HistoricalHeaderWitness", - "components": [ - { - "name": "header", - "type": "tuple", - "internalType": "struct BeaconBlockHeader", - "components": [ - { - "name": "slot", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "proposerIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "parentRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "stateRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "bodyRoot", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "name": "rootGIndex", - "type": "bytes32", - "internalType": "GIndex" - }, - { - "name": "proof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ] - }, - { - "name": "witness", - "type": "tuple", - "internalType": "struct ICSVerifier.WithdrawalWitness", - "components": [ - { - "name": "withdrawalOffset", - "type": "uint8", - "internalType": "uint8" - }, - { - "name": "withdrawalIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "validatorIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "amount", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "withdrawalCredentials", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "effectiveBalance", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "slashed", - "type": "bool", - "internalType": "bool" - }, - { - "name": "activationEligibilityEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "activationEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "exitEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "withdrawableEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "withdrawalProof", - "type": "bytes32[]", - "internalType": "bytes32[]" - }, - { - "name": "validatorProof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ] - }, - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "keyIndex", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "processSlashingProof", - "inputs": [ - { - "name": "beaconBlock", - "type": "tuple", - "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", - "components": [ - { - "name": "header", - "type": "tuple", - "internalType": "struct BeaconBlockHeader", - "components": [ - { - "name": "slot", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "proposerIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "parentRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "stateRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "bodyRoot", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "name": "rootsTimestamp", - "type": "uint64", - "internalType": "uint64" - } - ] - }, - { - "name": "witness", - "type": "tuple", - "internalType": "struct ICSVerifier.SlashingWitness", - "components": [ - { - "name": "validatorIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "withdrawalCredentials", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "effectiveBalance", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "activationEligibilityEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "activationEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "exitEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "withdrawableEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "validatorProof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ] - }, - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "keyIndex", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "processWithdrawalProof", - "inputs": [ - { - "name": "beaconBlock", - "type": "tuple", - "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", - "components": [ - { - "name": "header", - "type": "tuple", - "internalType": "struct BeaconBlockHeader", - "components": [ - { - "name": "slot", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "proposerIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "parentRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "stateRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "bodyRoot", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "name": "rootsTimestamp", - "type": "uint64", - "internalType": "uint64" - } - ] - }, - { - "name": "witness", - "type": "tuple", - "internalType": "struct ICSVerifier.WithdrawalWitness", - "components": [ - { - "name": "withdrawalOffset", - "type": "uint8", - "internalType": "uint8" - }, - { - "name": "withdrawalIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "validatorIndex", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "amount", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "withdrawalCredentials", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "effectiveBalance", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "slashed", - "type": "bool", - "internalType": "bool" - }, - { - "name": "activationEligibilityEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "activationEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "exitEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "withdrawableEpoch", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "withdrawalProof", - "type": "bytes32[]", - "internalType": "bytes32[]" - }, - { - "name": "validatorProof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ] - }, - { - "name": "nodeOperatorId", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "keyIndex", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "error", - "name": "IndexOutOfRange", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidBlockHeader", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidChainConfig", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidGIndex", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidWithdrawalAddress", - "inputs": [] - }, - { - "type": "error", - "name": "PartialWitdrawal", - "inputs": [] - }, - { - "type": "error", - "name": "RootNotFound", - "inputs": [] - }, - { - "type": "error", - "name": "UnsupportedSlot", - "inputs": [ - { - "name": "slot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "ValidatorNotWithdrawn", - "inputs": [] - }, - { - "type": "error", - "name": "BranchHasExtraItem", - "inputs": [] - }, - { - "type": "error", - "name": "BranchHasMissingItem", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidProof", - "inputs": [] - } -] \ No newline at end of file + { + "type": "constructor", + "inputs": [ + { + "name": "locator", + "type": "address", + "internalType": "address" + }, + { + "name": "module", + "type": "address", + "internalType": "address" + }, + { + "name": "slotsPerEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "gIFirstWithdrawalPrev", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "gIFirstWithdrawalCurr", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "gIFirstValidatorPrev", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "gIFirstValidatorCurr", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "gIHistoricalSummariesPrev", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "gIHistoricalSummariesCurr", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "firstSupportedSlot", + "type": "uint64", + "internalType": "Slot" + }, + { + "name": "pivotSlot", + "type": "uint64", + "internalType": "Slot" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "BEACON_ROOTS", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "FIRST_SUPPORTED_SLOT", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "Slot" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_FIRST_VALIDATOR_CURR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_FIRST_VALIDATOR_PREV", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_FIRST_WITHDRAWAL_CURR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_FIRST_WITHDRAWAL_PREV", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_HISTORICAL_SUMMARIES_CURR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GI_HISTORICAL_SUMMARIES_PREV", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "GIndex" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "LOCATOR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ILidoLocator" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MODULE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ICSModule" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PIVOT_SLOT", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "Slot" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "SLOTS_PER_EPOCH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "processHistoricalWithdrawalProof", + "inputs": [ + { + "name": "beaconBlock", + "type": "tuple", + "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", + "components": [ + { + "name": "header", + "type": "tuple", + "internalType": "struct BeaconBlockHeader", + "components": [ + { + "name": "slot", + "type": "uint64", + "internalType": "Slot" + }, + { + "name": "proposerIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "parentRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "stateRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bodyRoot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "rootsTimestamp", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "name": "oldBlock", + "type": "tuple", + "internalType": "struct ICSVerifier.HistoricalHeaderWitness", + "components": [ + { + "name": "header", + "type": "tuple", + "internalType": "struct BeaconBlockHeader", + "components": [ + { + "name": "slot", + "type": "uint64", + "internalType": "Slot" + }, + { + "name": "proposerIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "parentRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "stateRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bodyRoot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "rootGIndex", + "type": "bytes32", + "internalType": "GIndex" + }, + { + "name": "proof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ] + }, + { + "name": "witness", + "type": "tuple", + "internalType": "struct ICSVerifier.WithdrawalWitness", + "components": [ + { + "name": "withdrawalOffset", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "withdrawalIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "validatorIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalCredentials", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "effectiveBalance", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "slashed", + "type": "bool", + "internalType": "bool" + }, + { + "name": "activationEligibilityEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "activationEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "exitEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawableEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "validatorProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ] + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "processSlashingProof", + "inputs": [ + { + "name": "beaconBlock", + "type": "tuple", + "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", + "components": [ + { + "name": "header", + "type": "tuple", + "internalType": "struct BeaconBlockHeader", + "components": [ + { + "name": "slot", + "type": "uint64", + "internalType": "Slot" + }, + { + "name": "proposerIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "parentRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "stateRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bodyRoot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "rootsTimestamp", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "name": "witness", + "type": "tuple", + "internalType": "struct ICSVerifier.SlashingWitness", + "components": [ + { + "name": "validatorIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalCredentials", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "effectiveBalance", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "activationEligibilityEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "activationEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "exitEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawableEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "validatorProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ] + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "processWithdrawalProof", + "inputs": [ + { + "name": "beaconBlock", + "type": "tuple", + "internalType": "struct ICSVerifier.ProvableBeaconBlockHeader", + "components": [ + { + "name": "header", + "type": "tuple", + "internalType": "struct BeaconBlockHeader", + "components": [ + { + "name": "slot", + "type": "uint64", + "internalType": "Slot" + }, + { + "name": "proposerIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "parentRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "stateRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bodyRoot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "rootsTimestamp", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "name": "witness", + "type": "tuple", + "internalType": "struct ICSVerifier.WithdrawalWitness", + "components": [ + { + "name": "withdrawalOffset", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "withdrawalIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "validatorIndex", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "amount", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalCredentials", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "effectiveBalance", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "slashed", + "type": "bool", + "internalType": "bool" + }, + { + "name": "activationEligibilityEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "activationEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "exitEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawableEpoch", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "withdrawalProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "validatorProof", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ] + }, + { + "name": "nodeOperatorId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "keyIndex", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "error", + "name": "IndexOutOfRange", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBlockHeader", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidChainConfig", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidGIndex", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidPivotSlot", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidWithdrawalAddress", + "inputs": [] + }, + { + "type": "error", + "name": "PartialWithdrawal", + "inputs": [] + }, + { + "type": "error", + "name": "RootNotFound", + "inputs": [] + }, + { + "type": "error", + "name": "UnsupportedSlot", + "inputs": [ + { + "name": "slot", + "type": "uint64", + "internalType": "Slot" + } + ] + }, + { + "type": "error", + "name": "ValidatorNotWithdrawn", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroLocatorAddress", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroModuleAddress", + "inputs": [] + } + ] diff --git a/scripts/vote_sr_v2.py b/scripts/vote_sr_v2.py index b5ed6c58a..48250f6fd 100644 --- a/scripts/vote_sr_v2.py +++ b/scripts/vote_sr_v2.py @@ -373,8 +373,8 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T agent_forward( [ ( - contracts.csmHashConsensus.address, - contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), + contracts.csm_hash_consensus.address, + contracts.csm_hash_consensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), ) ] ), diff --git a/tests/acceptance/conftest.py b/tests/acceptance/conftest.py index 4e8d9c436..ebb0ef76d 100644 --- a/tests/acceptance/conftest.py +++ b/tests/acceptance/conftest.py @@ -12,9 +12,17 @@ ENV_REPORT_AFTER_VOTE = "REPORT_AFTER_VOTE" ENV_FILL_SIMPLE_DVT = "FILL_SIMPLE_DVT" +snapshot_id = None + @pytest.fixture(scope="function", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger): + global snapshot_id + + if snapshot_id: + print(f"Using snapshot {snapshot_id}") + chain._revert(snapshot_id) + return if vote_ids_from_env: helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") else: @@ -25,3 +33,5 @@ def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger): if os.getenv(ENV_REPORT_AFTER_VOTE): oracle_report(cl_diff=ETH(523), exclude_vaults_balances=False) + chain.snapshot() + snapshot_id = chain._snapshot_id diff --git a/tests/acceptance/test_csm.py b/tests/acceptance/test_csm.py new file mode 100644 index 000000000..fd1609461 --- /dev/null +++ b/tests/acceptance/test_csm.py @@ -0,0 +1,205 @@ +import pytest + +from brownie import interface, web3, Wei # type: ignore + +from utils.config import ( + contracts, + ContractsLazyLoader, + LIDO_LOCATOR, + LIDO, + WITHDRAWAL_QUEUE, + WSTETH_TOKEN, + STAKING_ROUTER, + AGENT, + BURNER, + CSM_ADDRESS, + CS_ACCOUNTING_ADDRESS, + CS_GATE_SEAL_ADDRESS, + CS_VERIFIER_ADDRESS, + CS_FEE_DISTRIBUTOR_ADDRESS, + CS_FEE_ORACLE_ADDRESS, + CS_ORACLE_HASH_CONSENSUS_ADDRESS, + EASYTRACK_EVMSCRIPT_EXECUTOR, + CHAIN_SECONDS_PER_SLOT, + CHAIN_GENESIS_TIME, + CHAIN_SLOTS_PER_EPOCH, + CS_ORACLE_EPOCHS_PER_FRAME, + ORACLE_QUORUM, + ORACLE_COMMITTEE +) + +contracts: ContractsLazyLoader = contracts + + +def _str_to_bytes32(s: str) -> str: + return "0x{:0<64}".format(s.encode("utf-8").hex()) + + +@pytest.fixture(scope="module") +def csm(): + return contracts.csm + +@pytest.fixture(scope="module") +def early_adoption(): + return contracts.cs_early_adoption + +@pytest.fixture(scope="module") +def fee_distributor(): + return contracts.cs_fee_distributor + +@pytest.fixture(scope="module") +def fee_oracle(): + return contracts.cs_fee_oracle + +@pytest.fixture(scope="module") +def hash_consensus(): + return contracts.csm_hash_consensus + +@pytest.fixture(scope="module") +def accounting(): + return contracts.cs_accounting + +@pytest.fixture(scope="module") +def verifier(): + return contracts.cs_verifier + + +@pytest.fixture(scope="module") +def lido(): + return interface.Lido(LIDO) + +def test_proxy(csm, accounting, fee_distributor, fee_oracle): + assert interface.OssifiableProxy(csm).proxy__getAdmin() == contracts.agent.address + assert interface.OssifiableProxy(accounting).proxy__getAdmin() == contracts.agent.address + assert interface.OssifiableProxy(fee_distributor).proxy__getAdmin() == contracts.agent.address + assert interface.OssifiableProxy(fee_oracle).proxy__getAdmin() == contracts.agent.address + + +class TestCSM: + def test_init_state(self, csm): + assert csm.getType() == _str_to_bytes32("community-onchain-v1") + assert csm.LIDO_LOCATOR() == LIDO_LOCATOR + assert csm.accounting() == CS_ACCOUNTING_ADDRESS + + assert not csm.isPaused(); + assert not csm.publicRelease(); + assert csm.getNodeOperatorsCount() == 0; + + + def test_roles(self, csm): + assert csm.hasRole(csm.STAKING_ROUTER_ROLE(), STAKING_ROUTER) + assert csm.hasRole(csm.DEFAULT_ADMIN_ROLE(), AGENT) + assert csm.hasRole(csm.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) + assert csm.hasRole(csm.SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE(), EASYTRACK_EVMSCRIPT_EXECUTOR) + assert csm.hasRole(csm.VERIFIER_ROLE(), CS_VERIFIER_ADDRESS) + +class TestAccounting: + def test_initial_state(self, accounting): + assert accounting.CSM() == CSM_ADDRESS + assert accounting.LIDO_LOCATOR() == LIDO_LOCATOR + assert accounting.LIDO() == LIDO + assert accounting.WITHDRAWAL_QUEUE() == WITHDRAWAL_QUEUE + assert accounting.WSTETH() == WSTETH_TOKEN + assert accounting.feeDistributor() == CS_FEE_DISTRIBUTOR_ADDRESS + assert accounting.chargePenaltyRecipient() == AGENT + assert not accounting.isPaused() + + def test_roles(self, accounting): + assert accounting.hasRole(accounting.SET_BOND_CURVE_ROLE(), CSM_ADDRESS) + assert accounting.hasRole(accounting.RESET_BOND_CURVE_ROLE(), CSM_ADDRESS) + assert accounting.hasRole(accounting.DEFAULT_ADMIN_ROLE(), AGENT) + assert accounting.hasRole(accounting.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) + + def test_allowances(self, lido): + uin256_max = 2 ** 256 - 1 + assert lido.allowance(CS_ACCOUNTING_ADDRESS, WSTETH_TOKEN) == uin256_max + assert lido.allowance(CS_ACCOUNTING_ADDRESS, WITHDRAWAL_QUEUE) == uin256_max + assert lido.allowance(CS_ACCOUNTING_ADDRESS, BURNER) == uin256_max + +class TestFeeDistributor: + + def test_initial_state(self, fee_distributor): + assert fee_distributor.STETH() == LIDO + assert fee_distributor.ACCOUNTING() == CS_ACCOUNTING_ADDRESS + assert fee_distributor.ORACLE() == CS_FEE_ORACLE_ADDRESS + assert fee_distributor.totalClaimableShares() == 0 + assert fee_distributor.pendingSharesToDistribute() == 0 + assert fee_distributor.treeRoot() == _str_to_bytes32("") + assert fee_distributor.treeCid() == "" + + def test_roles(self, fee_distributor): + assert fee_distributor.hasRole(fee_distributor.DEFAULT_ADMIN_ROLE(), AGENT) + + +class TestFeeOracle: + + def test_initial_state(self, fee_oracle): + assert fee_oracle.SECONDS_PER_SLOT() == CHAIN_SECONDS_PER_SLOT + assert fee_oracle.GENESIS_TIME() == CHAIN_GENESIS_TIME + assert fee_oracle.feeDistributor() == CS_FEE_DISTRIBUTOR_ADDRESS + assert fee_oracle.getContractVersion() == 1 + assert fee_oracle.getConsensusContract() == CS_ORACLE_HASH_CONSENSUS_ADDRESS + assert fee_oracle.getConsensusVersion() == 1 + assert fee_oracle.getLastProcessingRefSlot() == 0 + assert fee_oracle.avgPerfLeewayBP() == 500 + assert not fee_oracle.isPaused() + + report = fee_oracle.getConsensusReport() + assert report["hash"] == _str_to_bytes32("") + assert report["refSlot"] == 0 + assert report["processingDeadlineTime"] == 0 + assert not report["processingStarted"] + + + def test_roles(self, fee_oracle): + assert fee_oracle.hasRole(fee_oracle.DEFAULT_ADMIN_ROLE(), AGENT) + assert fee_oracle.hasRole(fee_oracle.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) + +class TestHashConsensus: + + def test_initial_state(self, hash_consensus): + current_frame = hash_consensus.getCurrentFrame() + # TODO uncomment this when initial ref slot is known + # assert current_frame["refSlot"] > 5254400 + # assert current_frame["reportProcessingDeadlineSlot"] > 5254400 + + chain_config = hash_consensus.getChainConfig() + assert chain_config["slotsPerEpoch"] == CHAIN_SLOTS_PER_EPOCH + assert chain_config["secondsPerSlot"] == CHAIN_SECONDS_PER_SLOT + assert chain_config["genesisTime"] == CHAIN_GENESIS_TIME + + frame_config = hash_consensus.getFrameConfig() + # TODO uncomment this when initial ref slot is known + # assert frame_config["initialEpoch"] > 5254400 / CHAIN_SLOTS_PER_EPOCH + assert frame_config["epochsPerFrame"] == CS_ORACLE_EPOCHS_PER_FRAME + assert frame_config["fastLaneLengthSlots"] == 0 + + assert hash_consensus.getQuorum() == ORACLE_QUORUM + + # TODO uncomment this when initial ref slot is known + # assert hash_consensus.getInitialRefSlot() > 5254400 + + members = hash_consensus.getMembers() + assert members["addresses"] == ORACLE_COMMITTEE + + assert hash_consensus.getReportProcessor() == CS_FEE_ORACLE_ADDRESS + + def test_roles(self, hash_consensus): + assert hash_consensus.hasRole(hash_consensus.DEFAULT_ADMIN_ROLE(), AGENT) + +def test_early_adoption_state(early_adoption): + assert early_adoption.MODULE() == CSM_ADDRESS + assert early_adoption.CURVE_ID() == 1 + +def test_verifier_state(verifier): + assert verifier.LOCATOR() == LIDO_LOCATOR + assert verifier.MODULE() == CSM_ADDRESS + assert verifier.SLOTS_PER_EPOCH() == CHAIN_SLOTS_PER_EPOCH + # TODO uncomment this when values are known + # assert verifier.GI_HISTORICAL_SUMMARIES_PREV() == "" + # assert verifier.GI_HISTORICAL_SUMMARIES_CURR() == "" + # assert verifier.GI_FIRST_WITHDRAWAL_PREV() == "" + # assert verifier.GI_FIRST_WITHDRAWAL_CURR() == "" + # assert verifier.GI_FIRST_VALIDATOR_PREV() == "" + # assert verifier.GI_FIRST_VALIDATOR_CURR() == "" + # assert verifier.FIRST_SUPPORTED_SLOT() == "" diff --git a/tests/test_vote_sr_v2.py b/tests/test_vote_sr_v2.py index 9b03b46cf..847004e43 100644 --- a/tests/test_vote_sr_v2.py +++ b/tests/test_vote_sr_v2.py @@ -12,7 +12,7 @@ SIMPLE_DVT_IMPL, ACCOUNTING_ORACLE_IMPL, CS_ACCOUNTING_ADDRESS, - CSM, + CSM_ADDRESS, ) from scripts.mainnet.vote_sr_v2_mainnet import ( start_vote, @@ -147,7 +147,7 @@ class StakingModuleItem(NamedTuple): CSM_AFTER_VOTE = { "id": 3, "name": CS_MODULE_NAME, - "stakingModuleAddress": CSM, + "stakingModuleAddress": CSM_ADDRESS, "stakingModuleFee": CS_STAKING_MODULE_FEE, "treasuryFee": CS_TREASURY_FEE, "targetShare": CS_STAKE_SHARE_LIMIT, @@ -251,7 +251,7 @@ def test_vote( # AO check_ossifiable_proxy_impl(ao_proxy, ACCOUNTING_ORACLE_IMPL) - # no prermission to manage consensus version on agent + # no permission to manage consensus version on agent check_manage_consensus_role() # VEBO consensus version assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION @@ -259,7 +259,7 @@ def test_vote( assert contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) - assert contracts.csmHashConsensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + assert contracts.csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH check_csm() @@ -459,7 +459,7 @@ def validate_upgrade_events(events: EventDict, implementation: str): assert events["Upgraded"]["implementation"] == implementation, "Wrong withdrawal vault proxy implementation" -def validate_dsm_roles_events(events: EventDict): +def validate_dsm_roles_events(events: list[EventDict]): validate_revoke_role_event( events[1], PAUSE_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address ) diff --git a/utils/config.py b/utils/config.py index ba8c18927..16aa118de 100644 --- a/utils/config.py +++ b/utils/config.py @@ -177,12 +177,32 @@ def simple_dvt(self) -> interface.SimpleDVT: @property def csm(self) -> interface.CSModule: - return interface.CSModule(CSM) + return interface.CSModule(CSM_ADDRESS) @property - def csmHashConsensus(self) -> interface.CSHashConsensus: + def cs_early_adoption(self) -> interface.CSEarlyAdoption: + return interface.CSEarlyAdoption(CS_EARLY_ADOPTION_ADDRESS) + + @property + def cs_accounting(self) -> interface.CSAccounting: + return interface.CSAccounting(CS_ACCOUNTING_ADDRESS) + + @property + def cs_fee_distributor(self) -> interface.CSFeeDistributor: + return interface.CSFeeDistributor(CS_FEE_DISTRIBUTOR_ADDRESS) + + @property + def cs_fee_oracle(self) -> interface.CSFeeOracle: + return interface.CSFeeOracle(CS_FEE_ORACLE_ADDRESS) + + @property + def csm_hash_consensus(self) -> interface.CSHashConsensus: return interface.CSHashConsensus(CS_ORACLE_HASH_CONSENSUS_ADDRESS) + @property + def cs_verifier(self) -> interface.CSVerifier: + return interface.CSVerifier(CS_VERIFIER_ADDRESS) + @property def sandbox(self) -> interface.SimpleDVT: return interface.Sandbox(SANDBOX) diff --git a/utils/import_current_votes.py b/utils/import_current_votes.py index e77b6d62e..952ddf61e 100644 --- a/utils/import_current_votes.py +++ b/utils/import_current_votes.py @@ -5,12 +5,19 @@ from brownie import accounts from brownie.network.transaction import TransactionReceipt from utils.test.helpers import ETH -from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS, get_is_live, contracts +from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS, get_is_live, contracts, network_name + + +def _get_network(): + network = network_name().replace("-fork", "") + if network not in ("mainnet", "holesky", "sepolia", "goerli"): + network = "mainnet" + return network def get_vote_scripts_dir() -> str: dir_path = os.path.dirname(os.path.realpath(__file__)) - dir_path = os.path.join(os.path.split(dir_path)[0], "scripts") + dir_path = os.path.join(os.path.split(dir_path)[0], "scripts", _get_network()) return dir_path @@ -48,12 +55,13 @@ def start_and_execute_votes(dao_voting, helpers) -> tuple[List[str], List[Transa vote_files.extend(upgrade_files) assert len(vote_files) > 0 + network = _get_network() vote_ids = [] vote_transactions = [] for vote_file in sorted(vote_files): script_name = os.path.splitext(os.path.basename(vote_file))[0] print(f"Starting voting from script '{script_name}'...") - name_for_import = "scripts." + script_name + name_for_import = "scripts." + network + "." + script_name start_vote_name = f"start_vote_{script_name}" exec(f"from {name_for_import} import start_vote as {start_vote_name}") start_vote = locals()[start_vote_name] From b09e9fd825a6825763800da2dbfcb34633c84bd7 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Thu, 1 Aug 2024 09:27:32 +0500 Subject: [PATCH 100/220] Revert some changes --- archive/scripts/vote_sr_v2_holesky.py | 4 ++-- archive/tests/test_vote_sr_v2_holesky.py | 2 +- tests/acceptance/conftest.py | 11 ----------- utils/import_current_votes.py | 12 ++---------- 4 files changed, 5 insertions(+), 24 deletions(-) diff --git a/archive/scripts/vote_sr_v2_holesky.py b/archive/scripts/vote_sr_v2_holesky.py index 1ecc2f023..ee64c8aeb 100644 --- a/archive/scripts/vote_sr_v2_holesky.py +++ b/archive/scripts/vote_sr_v2_holesky.py @@ -358,8 +358,8 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T agent_forward( [ ( - contracts.csm_hash_consensus.address, - contracts.csm_hash_consensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), + contracts.csmHashConsensus.address, + contracts.csmHashConsensus.updateInitialEpoch.encode_input(CS_ORACLE_INITIAL_EPOCH), ) ] ), diff --git a/archive/tests/test_vote_sr_v2_holesky.py b/archive/tests/test_vote_sr_v2_holesky.py index 1a05e3736..7448f8da4 100644 --- a/archive/tests/test_vote_sr_v2_holesky.py +++ b/archive/tests/test_vote_sr_v2_holesky.py @@ -248,7 +248,7 @@ def test_vote(helpers, accounts, vote_ids_from_env, bypass_events_decoding): assert contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) - assert contracts.csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + assert contracts.csmHashConsensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH # Events check if bypass_events_decoding: diff --git a/tests/acceptance/conftest.py b/tests/acceptance/conftest.py index ebb0ef76d..a6cb26301 100644 --- a/tests/acceptance/conftest.py +++ b/tests/acceptance/conftest.py @@ -7,22 +7,13 @@ from utils.test.helpers import ETH from utils.test.oracle_report_helpers import oracle_report from utils.test.simple_dvt_helpers import fill_simple_dvt_ops_vetted_keys -from brownie import chain ENV_REPORT_AFTER_VOTE = "REPORT_AFTER_VOTE" ENV_FILL_SIMPLE_DVT = "FILL_SIMPLE_DVT" -snapshot_id = None - @pytest.fixture(scope="function", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger): - global snapshot_id - - if snapshot_id: - print(f"Using snapshot {snapshot_id}") - chain._revert(snapshot_id) - return if vote_ids_from_env: helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") else: @@ -33,5 +24,3 @@ def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger): if os.getenv(ENV_REPORT_AFTER_VOTE): oracle_report(cl_diff=ETH(523), exclude_vaults_balances=False) - chain.snapshot() - snapshot_id = chain._snapshot_id diff --git a/utils/import_current_votes.py b/utils/import_current_votes.py index 952ddf61e..d707e5b3c 100644 --- a/utils/import_current_votes.py +++ b/utils/import_current_votes.py @@ -8,16 +8,9 @@ from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS, get_is_live, contracts, network_name -def _get_network(): - network = network_name().replace("-fork", "") - if network not in ("mainnet", "holesky", "sepolia", "goerli"): - network = "mainnet" - return network - - def get_vote_scripts_dir() -> str: dir_path = os.path.dirname(os.path.realpath(__file__)) - dir_path = os.path.join(os.path.split(dir_path)[0], "scripts", _get_network()) + dir_path = os.path.join(os.path.split(dir_path)[0], "scripts") return dir_path @@ -55,13 +48,12 @@ def start_and_execute_votes(dao_voting, helpers) -> tuple[List[str], List[Transa vote_files.extend(upgrade_files) assert len(vote_files) > 0 - network = _get_network() vote_ids = [] vote_transactions = [] for vote_file in sorted(vote_files): script_name = os.path.splitext(os.path.basename(vote_file))[0] print(f"Starting voting from script '{script_name}'...") - name_for_import = "scripts." + network + "." + script_name + name_for_import = "scripts." + script_name start_vote_name = f"start_vote_{script_name}" exec(f"from {name_for_import} import start_vote as {start_vote_name}") start_vote = locals()[start_vote_name] From 50718c9a2f0d0fc2f11b39b72e31ae952153ab32 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Thu, 1 Aug 2024 14:30:30 +0500 Subject: [PATCH 101/220] removed unused imports --- utils/import_current_votes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/import_current_votes.py b/utils/import_current_votes.py index d707e5b3c..d7269b8d2 100644 --- a/utils/import_current_votes.py +++ b/utils/import_current_votes.py @@ -5,7 +5,7 @@ from brownie import accounts from brownie.network.transaction import TransactionReceipt from utils.test.helpers import ETH -from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS, get_is_live, contracts, network_name +from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS, contracts def get_vote_scripts_dir() -> str: From 59fddd79e5aeff8a6444d3daa1d2192a3c29b1db Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 1 Aug 2024 17:46:31 +0200 Subject: [PATCH 102/220] test: update target limit test for both curated and csm modules --- .../test_node_operators_registry.py | 56 -------------- tests/acceptance/test_staking_module.py | 76 +++++++++++++++++++ 2 files changed, 76 insertions(+), 56 deletions(-) create mode 100644 tests/acceptance/test_staking_module.py diff --git a/tests/acceptance/test_node_operators_registry.py b/tests/acceptance/test_node_operators_registry.py index 810d93753..e695f99ee 100644 --- a/tests/acceptance/test_node_operators_registry.py +++ b/tests/acceptance/test_node_operators_registry.py @@ -1,8 +1,5 @@ import pytest from brownie import ZERO_ADDRESS, interface, web3, reverts # type: ignore -from brownie.network.account import Account -from brownie import convert -from web3 import Web3 from utils.config import ( contracts, @@ -156,58 +153,5 @@ def test_nor_state(contract): assert node_operator_summary["depositableValidatorsCount"] == no_depositable_validators_count -def test_update_target_validators_limits(contract, voting, stranger): - operator_id = contract.getNodeOperatorsCount() - - with reverts("APP_AUTH_FAILED"): - contract.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) - - contracts.acl.grantPermission( - stranger, - contract, - convert.to_uint(Web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE")), - {"from": voting}, - ) - - contract.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) - - node_operator = contract.getNodeOperatorSummary(operator_id) - assert node_operator["targetLimitMode"] == 0 - assert node_operator["targetValidatorsCount"] == 0 - - with reverts("APP_AUTH_FAILED"): - contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 1, 10, {"from": stranger}) - - contracts.acl.grantPermission( - stranger, - contract, - convert.to_uint(Web3.keccak(text="STAKING_ROUTER_ROLE")), - {"from": voting}, - ) - - with reverts("OUT_OF_RANGE"): - contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id + 1, 1, 10, {"from": stranger}) - - contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 1, 10, {"from": stranger}) - node_operator = contract.getNodeOperatorSummary(operator_id) - assert node_operator["targetLimitMode"] == 1 - assert node_operator["targetValidatorsCount"] == 10 - - contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 2, 20, {"from": stranger}) - node_operator = contract.getNodeOperatorSummary(operator_id) - assert node_operator["targetLimitMode"] == 2 - assert node_operator["targetValidatorsCount"] == 20 - - # any target mode value great then 2 will be treat as force mode - contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 3, 30, {"from": stranger}) - node_operator = contract.getNodeOperatorSummary(operator_id) - assert node_operator["targetLimitMode"] == 3 - assert node_operator["targetValidatorsCount"] == 30 - - contract.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 0, 40, {"from": stranger}) - node_operator = contract.getNodeOperatorSummary(operator_id) - assert node_operator["targetLimitMode"] == 0 - assert node_operator["targetValidatorsCount"] == 0 # should be always 0 in disabled mode - def _str_to_bytes32(s: str) -> str: return "0x{:0<64}".format(s.encode("utf-8").hex()) diff --git a/tests/acceptance/test_staking_module.py b/tests/acceptance/test_staking_module.py new file mode 100644 index 000000000..60087e0f3 --- /dev/null +++ b/tests/acceptance/test_staking_module.py @@ -0,0 +1,76 @@ +import pytest +from brownie import interface, reverts # type: ignore +from brownie.network.account import Account +from brownie import convert +from web3 import Web3 + +from utils.config import ( + contracts, + NODE_OPERATORS_REGISTRY, + SIMPLE_DVT, +) + +@pytest.fixture +def voting(accounts): + return accounts.at(contracts.voting.address, force=True) + +def update_target_validators_limits(staking_module, voting, stranger): + operator_id = staking_module.getNodeOperatorsCount() + + with reverts("APP_AUTH_FAILED"): + staking_module.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) + + contracts.acl.grantPermission( + stranger, + staking_module, + convert.to_uint(Web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE")), + {"from": voting}, + ) + + staking_module.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) + + node_operator = staking_module.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 0 + assert node_operator["targetValidatorsCount"] == 0 + + with reverts("APP_AUTH_FAILED"): + staking_module.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 1, 10, {"from": stranger}) + + contracts.acl.grantPermission( + stranger, + staking_module, + convert.to_uint(Web3.keccak(text="STAKING_ROUTER_ROLE")), + {"from": voting}, + ) + + with reverts("OUT_OF_RANGE"): + staking_module.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id + 1, 1, 10, {"from": stranger}) + + staking_module.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 1, 10, {"from": stranger}) + node_operator = staking_module.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 1 + assert node_operator["targetValidatorsCount"] == 10 + + staking_module.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 2, 20, {"from": stranger}) + node_operator = staking_module.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 2 + assert node_operator["targetValidatorsCount"] == 20 + + # any target mode value great then 2 will be treat as force mode + staking_module.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 3, 30, {"from": stranger}) + node_operator = staking_module.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 3 + assert node_operator["targetValidatorsCount"] == 30 + + staking_module.updateTargetValidatorsLimits['uint256,uint256,uint256'](operator_id, 0, 40, {"from": stranger}) + node_operator = staking_module.getNodeOperatorSummary(operator_id) + assert node_operator["targetLimitMode"] == 0 + assert node_operator["targetValidatorsCount"] == 0 # should be always 0 in disabled mode + +def test_curated_module_update_target_validators_limits(voting, stranger): + staking_module = interface.NodeOperatorsRegistry(NODE_OPERATORS_REGISTRY) + update_target_validators_limits(staking_module, voting, stranger) + +def test_simple_dvt_module_update_target_validators_limits(voting, stranger): + staking_module = interface.SimpleDVT(SIMPLE_DVT) + update_target_validators_limits(staking_module, voting, stranger) From e4dec2f9206f44994d901e907a2ff4b0ea33d44f Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 1 Aug 2024 23:16:10 +0200 Subject: [PATCH 103/220] test: decrease vetted signing keys count --- tests/acceptance/test_staking_module.py | 128 +++++++++++++++++++++++- 1 file changed, 127 insertions(+), 1 deletion(-) diff --git a/tests/acceptance/test_staking_module.py b/tests/acceptance/test_staking_module.py index 60087e0f3..55fd1c262 100644 --- a/tests/acceptance/test_staking_module.py +++ b/tests/acceptance/test_staking_module.py @@ -3,6 +3,7 @@ from brownie.network.account import Account from brownie import convert from web3 import Web3 +from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch from utils.config import ( contracts, @@ -14,7 +15,18 @@ def voting(accounts): return accounts.at(contracts.voting.address, force=True) -def update_target_validators_limits(staking_module, voting, stranger): +def prep_ids_counts_payload(ids, counts): + return { + 'operator_ids': "0x" + "".join(number_to_hex(id, 8) for id in ids), + 'keys_counts': "0x" + "".join(number_to_hex(count, 16) for count in counts), + } + +def number_to_hex(n, byte_len=None): + s = hex(n)[2:] # Convert to hex and remove the '0x' prefix + return s if byte_len is None else s.zfill(byte_len * 2) + + +def add_node_operator(staking_module, voting, stranger): operator_id = staking_module.getNodeOperatorsCount() with reverts("APP_AUTH_FAILED"): @@ -29,6 +41,11 @@ def update_target_validators_limits(staking_module, voting, stranger): staking_module.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) + return operator_id + +def update_target_validators_limits(staking_module, voting, stranger): + operator_id = add_node_operator(staking_module, voting, stranger) + node_operator = staking_module.getNodeOperatorSummary(operator_id) assert node_operator["targetLimitMode"] == 0 assert node_operator["targetValidatorsCount"] == 0 @@ -67,6 +84,107 @@ def update_target_validators_limits(staking_module, voting, stranger): assert node_operator["targetLimitMode"] == 0 assert node_operator["targetValidatorsCount"] == 0 # should be always 0 in disabled mode + +def decrease_vetted_signing_keys_count(staking_module, voting, stranger): + operator_id = add_node_operator(staking_module, voting, stranger) + operator = staking_module.getNodeOperator(operator_id, True) + + keys_count = 10 + staking_module.addSigningKeys( + operator_id, + keys_count, + random_pubkeys_batch(keys_count), + random_signatures_batch(keys_count), + {"from": operator["rewardAddress"]}, + ) + + contracts.acl.grantPermission( + stranger, + staking_module, + convert.to_uint(Web3.keccak(text="SET_NODE_OPERATOR_LIMIT_ROLE")), + {"from": voting}, + ) + + staking_module.setNodeOperatorStakingLimit(operator_id, 8, {"from": stranger}) + + node_operator_before_unvetting = staking_module.getNodeOperator(operator_id, True) + assert node_operator_before_unvetting["totalAddedValidators"] == keys_count + assert node_operator_before_unvetting["totalVettedValidators"] == 8 + + ids_counts_payload = prep_ids_counts_payload([operator_id], [6]) + + with reverts("APP_AUTH_FAILED"): + staking_module.decreaseVettedSigningKeysCount( + ids_counts_payload["operator_ids"], + ids_counts_payload["keys_counts"], + {"from": stranger} + ) + + contracts.acl.grantPermission( + stranger, + staking_module, + convert.to_uint(Web3.keccak(text="STAKING_ROUTER_ROLE")), + {"from": voting}, + ) + + with reverts("OUT_OF_RANGE"): + ids_counts_payload_invalid_id = prep_ids_counts_payload([operator_id + 1], [6]) + staking_module.decreaseVettedSigningKeysCount( + ids_counts_payload_invalid_id["operator_ids"], + ids_counts_payload_invalid_id["keys_counts"], + {"from": stranger} + ) + + with reverts("VETTED_KEYS_COUNT_INCREASED"): + ids_counts_payload_increase = prep_ids_counts_payload([operator_id], [9]) + staking_module.decreaseVettedSigningKeysCount( + ids_counts_payload_increase["operator_ids"], + ids_counts_payload_increase["keys_counts"], + {"from": stranger} + ) + + with reverts("VETTED_KEYS_COUNT_INCREASED"): + ids_counts_payload_increase = prep_ids_counts_payload([operator_id], [11]) + staking_module.decreaseVettedSigningKeysCount( + ids_counts_payload_increase["operator_ids"], + ids_counts_payload_increase["keys_counts"], + {"from": stranger} + ) + + staking_module.decreaseVettedSigningKeysCount( + ids_counts_payload["operator_ids"], + ids_counts_payload["keys_counts"], + {"from": stranger} + ) + + node_operator_after_unvetting = staking_module.getNodeOperator(operator_id, True) + assert node_operator_after_unvetting["totalAddedValidators"] == keys_count + assert node_operator_after_unvetting["totalVettedValidators"] == 6 + + # second attempt to decrease keys count to the same value do nothing + staking_module.decreaseVettedSigningKeysCount( + ids_counts_payload["operator_ids"], + ids_counts_payload["keys_counts"], + {"from": stranger} + ) + + node_operator_after_unvetting = staking_module.getNodeOperator(operator_id, True) + assert node_operator_after_unvetting["totalAddedValidators"] == keys_count + assert node_operator_after_unvetting["totalVettedValidators"] == 6 + + # decrease to zero + ids_counts_zero_payload = prep_ids_counts_payload([operator_id], [0]) + staking_module.decreaseVettedSigningKeysCount( + ids_counts_zero_payload["operator_ids"], + ids_counts_zero_payload["keys_counts"], + {"from": stranger} + ) + + node_operator_after_unvetting = staking_module.getNodeOperator(operator_id, True) + assert node_operator_after_unvetting["totalAddedValidators"] == keys_count + assert node_operator_after_unvetting["totalVettedValidators"] == 0 + + def test_curated_module_update_target_validators_limits(voting, stranger): staking_module = interface.NodeOperatorsRegistry(NODE_OPERATORS_REGISTRY) update_target_validators_limits(staking_module, voting, stranger) @@ -74,3 +192,11 @@ def test_curated_module_update_target_validators_limits(voting, stranger): def test_simple_dvt_module_update_target_validators_limits(voting, stranger): staking_module = interface.SimpleDVT(SIMPLE_DVT) update_target_validators_limits(staking_module, voting, stranger) + +def test_curated_module_decrease_vetted_signing_keys_count(voting, stranger): + staking_module = interface.NodeOperatorsRegistry(NODE_OPERATORS_REGISTRY) + decrease_vetted_signing_keys_count(staking_module, voting, stranger) + +def test_simple_dvt_module_decrease_vetted_signing_keys_count(voting, stranger): + staking_module = interface.SimpleDVT(SIMPLE_DVT) + decrease_vetted_signing_keys_count(staking_module, voting, stranger) From b4e15e46024cb8dbb15131ea5396ff32e6185e3c Mon Sep 17 00:00:00 2001 From: maxim Date: Fri, 2 Aug 2024 13:25:44 +0200 Subject: [PATCH 104/220] test: move staking modules tests to regression --- tests/{acceptance => regression}/test_staking_module.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{acceptance => regression}/test_staking_module.py (100%) diff --git a/tests/acceptance/test_staking_module.py b/tests/regression/test_staking_module.py similarity index 100% rename from tests/acceptance/test_staking_module.py rename to tests/regression/test_staking_module.py From 06e8b4136c5bc7b5d26a289cc331764ae7b4bc07 Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 5 Aug 2024 13:59:39 +0200 Subject: [PATCH 105/220] test: test unvet message prefix --- tests/acceptance/test_dsm.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/acceptance/test_dsm.py b/tests/acceptance/test_dsm.py index ba4d377d8..9cc514dd1 100644 --- a/tests/acceptance/test_dsm.py +++ b/tests/acceptance/test_dsm.py @@ -68,3 +68,14 @@ def test_prefixes(dsm): ], ).hex() ) + assert ( + dsm.UNVET_MESSAGE_PREFIX() + == web3.solidity_keccak( + ["bytes32", "uint256", "address"], + [ + web3.keccak(text="lido.DepositSecurityModule.UNVET_MESSAGE").hex(), + 1, + DEPOSIT_SECURITY_MODULE, + ], + ).hex() + ) From b68c03989d254b9a2966661156e61db793cd4f47 Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 6 Aug 2024 09:55:45 +0200 Subject: [PATCH 106/220] test: add tests for dsm unvet signing keys --- tests/regression/test_dsm_keys_unvetting.py | 129 ++++++++++++++++++++ utils/dsm.py | 84 +++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 tests/regression/test_dsm_keys_unvetting.py create mode 100644 utils/dsm.py diff --git a/tests/regression/test_dsm_keys_unvetting.py b/tests/regression/test_dsm_keys_unvetting.py new file mode 100644 index 000000000..b7c06b396 --- /dev/null +++ b/tests/regression/test_dsm_keys_unvetting.py @@ -0,0 +1,129 @@ +import pytest +from brownie import accounts, interface, reverts, web3 +from web3 import Web3 +from utils.config import ( + contracts, + DSM_MAX_OPERATORS_PER_UNVETTING, + NODE_OPERATORS_REGISTRY, +) +from utils.dsm import DSMUnvetMessage, UnvetArgs +from utils.evm_script import encode_error +from typing import Tuple +import hashlib +from eth_keys import keys +from eth_utils import decode_hex + +STAKING_MODULE_ID = 1 + +def get_unvet_args(overriding_args: UnvetArgs) -> Tuple[int, str, int, int, str, str]: + block_number = overriding_args.block_number + block_hash = overriding_args.block_hash + staking_module_id = overriding_args.staking_module_id + nonce = overriding_args.nonce + node_operator_ids = overriding_args.node_operator_ids + vetted_signing_keys_counts = overriding_args.vetted_signing_keys_counts + + return block_number, block_hash, staking_module_id, nonce, node_operator_ids, vetted_signing_keys_counts + +@pytest.fixture(scope="module") +def dsm() -> interface.DepositSecurityModule: + return contracts.deposit_security_module + +@pytest.fixture +def voting(accounts): + return accounts.at(contracts.voting.address, force=True) + +@pytest.fixture +def agent(accounts): + return accounts.at(contracts.agent.address, force=True) + +@pytest.fixture +def new_guardian(accounts): + return accounts[9] + +def set_single_guardian(dsm, agent, new_guardian): + guardians = dsm.getGuardians() + dsm.addGuardian(new_guardian.address, 1, {"from": agent}) + + for guardian in guardians: + dsm.removeGuardian(guardian, 1, {"from": agent}) + + assert len(dsm.getGuardians()) == 1 + assert dsm.isGuardian(new_guardian.address) + +def to_bytes(number: int, final_length: int) -> str: + hex_string = format(number, 'x') + num_of_leading_zeroes_needed = final_length - len(hex_string) + + return bytes.fromhex( + '0' * num_of_leading_zeroes_needed + hex_string if num_of_leading_zeroes_needed > 0 else hex_string + ) + +def test_dsm_max_operators_per_unvetting(dsm, agent, stranger): + assert dsm.getMaxOperatorsPerUnvetting() == DSM_MAX_OPERATORS_PER_UNVETTING + + with reverts(encode_error("NotAnOwner(string)", [stranger.address.lower()])): + dsm.setMaxOperatorsPerUnvetting(1, {"from": stranger}) + + dsm.setMaxOperatorsPerUnvetting(1, {"from": agent}) + assert dsm.getMaxOperatorsPerUnvetting() == 1 + +def test_dsm_keys_unvetting_by_bot(dsm, agent, stranger): + private_key="0x516b8a7d9290502f5661da81f0cf43893e3d19cb9aea3c426cfb36e8186e9c09" + new_guardian = accounts.add(private_key=private_key) + + set_single_guardian(dsm, agent, new_guardian) + + staking_module_id= 1 + operator_id = 0 + block_number = web3.eth.get_block_number() + block = web3.eth.get_block(block_number) + staking_module_nonce = contracts.staking_router.getStakingModuleNonce(1) + + args = get_unvet_args(UnvetArgs( + block_number=block_number, + block_hash=block.hash, + staking_module_id=staking_module_id, + nonce=staking_module_nonce, + node_operator_ids=to_bytes(operator_id, 16), + vetted_signing_keys_counts=to_bytes(1, 32), + )) + + DSMUnvetMessage.set_message_prefix(dsm.UNVET_MESSAGE_PREFIX()) + valid_unvet_message = DSMUnvetMessage(*args) + (compact_r, compact_vs) = valid_unvet_message.sign(private_key) + + dsm.unvetSigningKeys(*args, (compact_r, compact_vs), {"from": stranger}) + +def test_dsm_keys_unvetting_by_guardian(dsm, agent, stranger): + new_guardian = stranger + + staking_module_id= 1 + operator_id = 0 + + staking_module = interface.NodeOperatorsRegistry(NODE_OPERATORS_REGISTRY) + node_operator_before_unvetting = staking_module.getNodeOperator(operator_id, True) + totalDepositedValidators = node_operator_before_unvetting["totalDepositedValidators"] + assert totalDepositedValidators > 1 + + block_number = web3.eth.get_block_number() + block = web3.eth.get_block(block_number) + staking_module_nonce = contracts.staking_router.getStakingModuleNonce(1) + + unvet_args = UnvetArgs( + block_number=block_number, + block_hash=block.hash, + staking_module_id=staking_module_id, + nonce=staking_module_nonce, + node_operator_ids=to_bytes(operator_id, 16), + # try to unvet less than totalDepositedValidators + vetted_signing_keys_counts=to_bytes(1, 32), + ) + + set_single_guardian(dsm, agent, new_guardian) + + dsm.unvetSigningKeys(*get_unvet_args(unvet_args), (0, 0), {"from": new_guardian.address}) + + node_operator_after_unvetting = staking_module.getNodeOperator(operator_id, True) + assert node_operator_after_unvetting["totalDepositedValidators"] == totalDepositedValidators + assert node_operator_after_unvetting["totalVettedValidators"] == totalDepositedValidators diff --git a/utils/dsm.py b/utils/dsm.py new file mode 100644 index 000000000..5874c3381 --- /dev/null +++ b/utils/dsm.py @@ -0,0 +1,84 @@ +from typing import Any, Dict +from eth_account import Account +from eth_account.datastructures import ( + SignedMessage, +) +from web3 import Web3 +from dataclasses import dataclass + +@dataclass +class UnvetArgs: + block_number: int = None + block_hash: str = None + staking_module_id: int = None + nonce: int = None + node_operator_ids: bytes = None + vetted_signing_keys_counts: bytes = None + +class DSMMessage: + MESSAGE_PREFIX: str = "" + + @classmethod + def set_message_prefix(cls, new_message_prefix: str): + cls.MESSAGE_PREFIX = new_message_prefix + + @property + def message_prefix(self) -> str: + if not self.MESSAGE_PREFIX: + raise ValueError("MESSAGE_PREFIX isn't set") + return self.MESSAGE_PREFIX + + @property + def hash(self) -> str: + raise NotImplementedError("Unimplemented") + + def sign(self, signer_private_key: str) -> Dict[str, Any]: + signedMessage = Account.signHash(self.hash, signer_private_key) + return to_eip2098(signedMessage) + + +class DSMUnvetMessage(DSMMessage): + def __init__(self, block_number: int, block_hash: str, staking_module: int, nonce: int, + node_operator_ids: str, vetted_signing_keys_counts: str): + super().__init__() + self.block_number = block_number + self.block_hash = block_hash + self.staking_module = staking_module + self.nonce = nonce + self.node_operator_ids = node_operator_ids + self.vetted_signing_keys_counts = vetted_signing_keys_counts + + @property + def hash(self) -> str: + return Web3.solidity_keccak( + ["bytes32", "uint256", "bytes32", "uint256", "uint256", "bytes", "bytes"], + [ + self.message_prefix, + self.block_number, + self.block_hash, + self.staking_module, + self.nonce, + self.node_operator_ids, + self.vetted_signing_keys_counts + ] + ).hex() + +def to_eip2098(signedMessage: SignedMessage) -> Dict[str, Any]: + r = signedMessage.r + s = signedMessage.s + v = signedMessage.v + + assert (r.bit_length() + 7) // 8 == 32 + assert (s.bit_length() + 7) // 8 == 32 + + if v not in (27, 28): + raise ValueError("Invalid v value. Must be 27 or 28.") + + r_bytes = r.to_bytes(32, byteorder='big') + s_bytes = s.to_bytes(32, byteorder='big') + + vs = bytearray(s_bytes) + if vs[0] >> 7 == 1: + raise ValueError("invalid signature 's' value") + vs[0] |= (v % 27) << 7 # set the first bit of vs to the v parity bit + return (r_bytes, bytes(vs)) From 83fd25a5f12c59b944db2bf3767995c6f2601c9f Mon Sep 17 00:00:00 2001 From: maxim Date: Tue, 6 Aug 2024 10:39:21 +0200 Subject: [PATCH 107/220] test: add dsm tests 1. fail to unvet keys by stranger without guardian signature 2. unvet some keys --- tests/regression/test_dsm_keys_unvetting.py | 89 +++++++++++++++++++-- tests/regression/test_staking_module.py | 23 +----- utils/staking_module.py | 24 ++++++ 3 files changed, 110 insertions(+), 26 deletions(-) create mode 100644 utils/staking_module.py diff --git a/tests/regression/test_dsm_keys_unvetting.py b/tests/regression/test_dsm_keys_unvetting.py index b7c06b396..3e24964bc 100644 --- a/tests/regression/test_dsm_keys_unvetting.py +++ b/tests/regression/test_dsm_keys_unvetting.py @@ -1,5 +1,5 @@ import pytest -from brownie import accounts, interface, reverts, web3 +from brownie import accounts, convert, interface, reverts, web3 from web3 import Web3 from utils.config import ( contracts, @@ -9,9 +9,8 @@ from utils.dsm import DSMUnvetMessage, UnvetArgs from utils.evm_script import encode_error from typing import Tuple -import hashlib -from eth_keys import keys -from eth_utils import decode_hex +from utils.staking_module import add_node_operator +from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch STAKING_MODULE_ID = 1 @@ -68,7 +67,35 @@ def test_dsm_max_operators_per_unvetting(dsm, agent, stranger): dsm.setMaxOperatorsPerUnvetting(1, {"from": agent}) assert dsm.getMaxOperatorsPerUnvetting() == 1 -def test_dsm_keys_unvetting_by_bot(dsm, agent, stranger): + +def test_dsm_keys_unvetting_by_stranger_without_guardian_sign(dsm, stranger): + staking_module_id= 1 + operator_id = 0 + block_number = web3.eth.get_block_number() + block = web3.eth.get_block(block_number) + staking_module_nonce = contracts.staking_router.getStakingModuleNonce(1) + + args = get_unvet_args(UnvetArgs( + block_number=block_number, + block_hash=block.hash, + staking_module_id=staking_module_id, + nonce=staking_module_nonce, + node_operator_ids=to_bytes(operator_id, 16), + vetted_signing_keys_counts=to_bytes(1, 32), + )) + + non_guardian_private_key="0x" + "1" * 64 + + DSMUnvetMessage.set_message_prefix(dsm.UNVET_MESSAGE_PREFIX()) + valid_unvet_message = DSMUnvetMessage(*args) + (compact_r, compact_vs) = valid_unvet_message.sign(non_guardian_private_key) + + with reverts(encode_error("InvalidSignature()")): + dsm.unvetSigningKeys(*args, (compact_r, compact_vs), {"from": stranger}) + + + +def test_dsm_keys_unvetting_by_stranger_with_guardian_sign(dsm, agent, stranger): private_key="0x516b8a7d9290502f5661da81f0cf43893e3d19cb9aea3c426cfb36e8186e9c09" new_guardian = accounts.add(private_key=private_key) @@ -127,3 +154,55 @@ def test_dsm_keys_unvetting_by_guardian(dsm, agent, stranger): node_operator_after_unvetting = staking_module.getNodeOperator(operator_id, True) assert node_operator_after_unvetting["totalDepositedValidators"] == totalDepositedValidators assert node_operator_after_unvetting["totalVettedValidators"] == totalDepositedValidators + + +def test_dsm_decrease_vetted_signing_keys_count(dsm, agent, voting, stranger): + staking_module_id= 1 + staking_module = interface.NodeOperatorsRegistry(NODE_OPERATORS_REGISTRY) + operator_id = add_node_operator(staking_module, voting, stranger) + operator = staking_module.getNodeOperator(operator_id, True) + + keys_count = 10 + staking_module.addSigningKeys( + operator_id, + keys_count, + random_pubkeys_batch(keys_count), + random_signatures_batch(keys_count), + {"from": operator["rewardAddress"]}, + ) + + contracts.acl.grantPermission( + stranger, + staking_module, + convert.to_uint(Web3.keccak(text="SET_NODE_OPERATOR_LIMIT_ROLE")), + {"from": voting}, + ) + + staking_module.setNodeOperatorStakingLimit(operator_id, 8, {"from": stranger}) + + node_operator_before_unvetting = staking_module.getNodeOperator(operator_id, True) + assert node_operator_before_unvetting["totalAddedValidators"] == keys_count + assert node_operator_before_unvetting["totalVettedValidators"] == 8 + + block_number = web3.eth.get_block_number() + block = web3.eth.get_block(block_number) + staking_module_nonce = contracts.staking_router.getStakingModuleNonce(1) + vetted_signing_keys_counts_after_unvet = 4 + unvet_args = UnvetArgs( + block_number=block_number, + block_hash=block.hash, + staking_module_id=staking_module_id, + nonce=staking_module_nonce, + node_operator_ids=to_bytes(operator_id, 16), + # try to unvet less than totalDepositedValidators + vetted_signing_keys_counts=to_bytes(vetted_signing_keys_counts_after_unvet, 32), + ) + + new_guardian = stranger + set_single_guardian(dsm, agent, new_guardian) + + dsm.unvetSigningKeys(*get_unvet_args(unvet_args), (0, 0), {"from": new_guardian.address}) + node_operator_after_unvetting = staking_module.getNodeOperator(operator_id, True) + assert node_operator_after_unvetting["totalVettedValidators"] == vetted_signing_keys_counts_after_unvet + + diff --git a/tests/regression/test_staking_module.py b/tests/regression/test_staking_module.py index 55fd1c262..2eb193d73 100644 --- a/tests/regression/test_staking_module.py +++ b/tests/regression/test_staking_module.py @@ -1,8 +1,7 @@ import pytest -from brownie import interface, reverts # type: ignore -from brownie.network.account import Account -from brownie import convert +from brownie import convert, interface, reverts # type: ignore from web3 import Web3 +from utils.staking_module import add_node_operator from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch from utils.config import ( @@ -25,24 +24,6 @@ def number_to_hex(n, byte_len=None): s = hex(n)[2:] # Convert to hex and remove the '0x' prefix return s if byte_len is None else s.zfill(byte_len * 2) - -def add_node_operator(staking_module, voting, stranger): - operator_id = staking_module.getNodeOperatorsCount() - - with reverts("APP_AUTH_FAILED"): - staking_module.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) - - contracts.acl.grantPermission( - stranger, - staking_module, - convert.to_uint(Web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE")), - {"from": voting}, - ) - - staking_module.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) - - return operator_id - def update_target_validators_limits(staking_module, voting, stranger): operator_id = add_node_operator(staking_module, voting, stranger) diff --git a/utils/staking_module.py b/utils/staking_module.py new file mode 100644 index 000000000..7b639b44b --- /dev/null +++ b/utils/staking_module.py @@ -0,0 +1,24 @@ +from brownie import reverts # type: ignore +from brownie import convert +from web3 import Web3 + +from utils.config import ( + contracts, +) + +def add_node_operator(staking_module, voting, stranger): + operator_id = staking_module.getNodeOperatorsCount() + + with reverts("APP_AUTH_FAILED"): + staking_module.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) + + contracts.acl.grantPermission( + stranger, + staking_module, + convert.to_uint(Web3.keccak(text="MANAGE_NODE_OPERATOR_ROLE")), + {"from": voting}, + ) + + staking_module.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) + + return operator_id From 23f6b3d6d639c654bf51c87c35f59709067ebf8d Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 7 Aug 2024 13:34:15 +0200 Subject: [PATCH 108/220] refactor: oracle report helper extra data multi transaction --- .../test_accounting_oracle_negative.py | 6 +++--- .../test_accounting_oracle_extra_data.py | 2 +- ...accounting_oracle_extra_data_full_items.py | 2 +- tests/regression/test_sanity_checks.py | 4 ++-- .../test_staking_module_happy_path.py | 6 +++--- utils/test/extra_data.py | 11 ++++++---- utils/test/oracle_report_helpers.py | 20 +++++++++---------- 7 files changed, 27 insertions(+), 24 deletions(-) diff --git a/tests/acceptance/test_accounting_oracle_negative.py b/tests/acceptance/test_accounting_oracle_negative.py index f514fdc92..05a41f548 100644 --- a/tests/acceptance/test_accounting_oracle_negative.py +++ b/tests/acceptance/test_accounting_oracle_negative.py @@ -355,7 +355,7 @@ def extra_data_service(self): def report(self, extra_data: bytes, items_count: int = 2): oracle_report( - extraDataHash=Web3.keccak(extra_data), + extraDataHashList=[Web3.keccak(extra_data)], extraDataItemsCount=items_count, extraDataFormat=EXTRA_DATA_FORMAT_LIST, extraDataList=[extra_data], @@ -481,7 +481,7 @@ def test_extra_data_broken( push_report: Callable, ): report = oracle_report( - extraDataHash=HexBytes(NON_ZERO_HASH), + extraDataHashList=[HexBytes(NON_ZERO_HASH)], dry_run=True, ) push_report(report) @@ -549,7 +549,7 @@ def test_extra_data_broken( report = oracle_report( extraDataFormat=EXTRA_DATA_FORMAT_LIST, - extraDataHash=HexBytes(ZERO_HASH), + extraDataHashList=[HexBytes(ZERO_HASH)], extraDataItemsCount=42, dry_run=True, ) diff --git a/tests/regression/test_accounting_oracle_extra_data.py b/tests/regression/test_accounting_oracle_extra_data.py index 689c8d894..8a55e55c4 100644 --- a/tests/regression/test_accounting_oracle_extra_data.py +++ b/tests/regression/test_accounting_oracle_extra_data.py @@ -28,7 +28,7 @@ def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): oracle_report( extraDataFormat=1, - extraDataHash=extra_data.data_hash, + extraDataHashList=extra_data.extra_data_hash_list, extraDataItemsCount=item_count, extraDataList=extra_data.extra_data_list, ) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 2e5ad8e4f..34d0e842f 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -129,7 +129,7 @@ def test_extra_data_full_items( # Perform report (report_tx, _) = oracle_report( extraDataFormat=1, - extraDataHash=extra_data.data_hash, + extraDataHashList=extra_data.extra_data_hash_list, extraDataItemsCount=(nor_exited_items + nor_stuck_items + sdvt_exited_items + sdvt_stuck_items), extraDataList=extra_data.extra_data_list, stakingModuleIdsWithNewlyExitedValidators=modules_with_exited, diff --git a/tests/regression/test_sanity_checks.py b/tests/regression/test_sanity_checks.py index 641655538..53cbde3c2 100644 --- a/tests/regression/test_sanity_checks.py +++ b/tests/regression/test_sanity_checks.py @@ -233,7 +233,7 @@ def test_accounting_oracle_too_much_extra_data(extra_data_service): ): oracle_report( extraDataFormat=1, - extraDataHash=extra_data.data_hash, + extraDataHashList=extra_data.extra_data_hash_list, extraDataItemsCount=item_count, extraDataList=extra_data.extra_data_list, ) @@ -251,7 +251,7 @@ def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): ): oracle_report( extraDataFormat=1, - extraDataHash=extra_data.data_hash, + extraDataHashList=extra_data.extra_data_hash_list, extraDataItemsCount=1, extraDataList=extra_data.extra_data_list, ) diff --git a/tests/regression/test_staking_module_happy_path.py b/tests/regression/test_staking_module_happy_path.py index 14032acfd..c0de9ffc5 100644 --- a/tests/regression/test_staking_module_happy_path.py +++ b/tests/regression/test_staking_module_happy_path.py @@ -239,7 +239,7 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e (report_tx, extra_report_tx_list) = oracle_report( exclude_vaults_balances=True, extraDataFormat=1, - extraDataHash=extra_data.data_hash, + extraDataHashList=extra_data.extra_data_hash_list, extraDataItemsCount=2, extraDataList=extra_data.extra_data_list, numExitedValidatorsByStakingModule=[nor_exited_count + 10], @@ -373,7 +373,7 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e cl_diff=ETH(10), exclude_vaults_balances=True, extraDataFormat=1, - extraDataHash=extra_data.data_hash, + extraDataHashList=extra_data.extra_data_hash_list, extraDataItemsCount=2, extraDataList=extra_data.extra_data_list, numExitedValidatorsByStakingModule=[nor_exited_count + 12], @@ -495,7 +495,7 @@ def module_happy_path(staking_module, extra_data_service, impersonated_voting, e (report_tx, extra_report_tx_list) = oracle_report( exclude_vaults_balances=True, extraDataFormat=1, - extraDataHash=extra_data.data_hash, + extraDataHashList=extra_data.extra_data_hash_list, extraDataItemsCount=2, extraDataList=extra_data.extra_data_list, numExitedValidatorsByStakingModule=[nor_exited_count + 12], diff --git a/utils/test/extra_data.py b/utils/test/extra_data.py index 743d8071f..f3df4abf0 100644 --- a/utils/test/extra_data.py +++ b/utils/test/extra_data.py @@ -41,7 +41,7 @@ class ExtraDataItem: @dataclass class ExtraData: extra_data_list: List[bytes] - data_hash: HexBytes + extra_data_hash_list: HexBytes format: int items_count: int @@ -87,7 +87,7 @@ def collect( stuck_payloads = cls.build_validators_payloads(stuck_validators, max_no_in_payload_count) exited_payloads = cls.build_validators_payloads(exited_validators, max_no_in_payload_count) items_count, txs = cls.build_extra_transactions_data(stuck_payloads, exited_payloads, max_items_count) - first_hash, hashed_txs = cls.add_hashes_to_transactions(txs) + extra_data_hash_list, hashed_txs = cls.add_hashes_to_transactions(txs) if items_count: extra_data_format = FormatList.EXTRA_DATA_FORMAT_LIST_NON_EMPTY @@ -97,7 +97,7 @@ def collect( return ExtraData( items_count=items_count, extra_data_list=hashed_txs, - data_hash=first_hash, + extra_data_hash_list=extra_data_hash_list, format=extra_data_format.value, ) @@ -172,16 +172,19 @@ def add_hashes_to_transactions(txs_data: list[bytes]) -> tuple[bytes, list[bytes txs_data.reverse() txs_with_hashes = [] + txs_hashes = [] next_hash = ZERO_HASH for tx in txs_data: full_tx_data = next_hash + tx txs_with_hashes.append(full_tx_data) next_hash = web3.keccak(full_tx_data) + txs_hashes.append(next_hash) txs_with_hashes.reverse() + txs_hashes.reverse() - return next_hash, txs_with_hashes + return txs_hashes, txs_with_hashes @staticmethod def batch(iterable, n): diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index a1f17fe11..41edd0ed6 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -73,7 +73,7 @@ def prepare_accounting_report( withdrawalFinalizationBatches=[], isBunkerMode=False, extraDataFormat=EXTRA_DATA_FORMAT_EMPTY, - extraDataHash=ZERO_BYTES32, + extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, ): report = AccountingReport( @@ -90,7 +90,7 @@ def prepare_accounting_report( int(simulatedShareRate), bool(isBunkerMode), int(extraDataFormat), - extraDataHash, + extraDataHashList[0], int(extraDataItemsCount), ) @@ -165,7 +165,7 @@ def push_oracle_report( withdrawalFinalizationBatches=[], isBunkerMode=False, extraDataFormat=0, - extraDataHash=ZERO_BYTES32, + extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, silent=False, extraDataList:List[bytes]=[], @@ -188,7 +188,7 @@ def push_oracle_report( withdrawalFinalizationBatches=withdrawalFinalizationBatches, isBunkerMode=isBunkerMode, extraDataFormat=extraDataFormat, - extraDataHash=extraDataHash, + extraDataHashList=extraDataHashList, extraDataItemsCount=extraDataItemsCount, ) submitter = reach_consensus(refSlot, hash, consensusVersion, contracts.hash_consensus_for_accounting_oracle, silent) @@ -222,7 +222,7 @@ def push_oracle_report( assert refSlot == currentFrameRefSlot assert mainDataHash == hash.hex() assert mainDataSubmitted - assert state_extraDataHash == extraDataHash.hex() + assert state_extraDataHash == extraDataHashList[-1].hex() assert state_extraDataFormat == extraDataFormat assert extraDataSubmitted assert state_extraDataItemsCount == extraDataItemsCount @@ -292,7 +292,7 @@ def oracle_report( skip_withdrawals=False, wait_to_next_report_time=True, extraDataFormat=0, - extraDataHash=ZERO_BYTES32, + extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, extraDataList:List[bytes]=[], stakingModuleIdsWithNewlyExitedValidators=[], @@ -320,7 +320,7 @@ def oracle_report( skip_withdrawals=False, wait_to_next_report_time=True, extraDataFormat=0, - extraDataHash=ZERO_BYTES32, + extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, extraDataList:List[bytes]=[], stakingModuleIdsWithNewlyExitedValidators=[], @@ -348,7 +348,7 @@ def oracle_report( skip_withdrawals=False, wait_to_next_report_time=True, extraDataFormat=0, - extraDataHash=ZERO_BYTES32, + extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, extraDataList:List[bytes]=[], stakingModuleIdsWithNewlyExitedValidators=[], @@ -438,7 +438,7 @@ def oracle_report( simulatedShareRate=simulatedShareRate, isBunkerMode=is_bunker, extraDataFormat=extraDataFormat, - extraDataHash=extraDataHash, + extraDataHash=extraDataHashList[0], extraDataItemsCount=extraDataItemsCount, ) @@ -452,7 +452,7 @@ def oracle_report( elRewardsVaultBalance=elRewardsVaultBalance, simulatedShareRate=simulatedShareRate, extraDataFormat=extraDataFormat, - extraDataHash=extraDataHash, + extraDataHashList=extraDataHashList, extraDataItemsCount=extraDataItemsCount, extraDataList=extraDataList, stakingModuleIdsWithNewlyExitedValidators=stakingModuleIdsWithNewlyExitedValidators, From 7d58f828d07dba73f2dd8a74d721306b70b57468 Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 7 Aug 2024 19:23:03 +0200 Subject: [PATCH 109/220] test: test extra data splited on multiple items --- .../test_accounting_oracle_extra_data.py | 72 ++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data.py b/tests/regression/test_accounting_oracle_extra_data.py index 8a55e55c4..2be416d57 100644 --- a/tests/regression/test_accounting_oracle_extra_data.py +++ b/tests/regression/test_accounting_oracle_extra_data.py @@ -1,7 +1,7 @@ import pytest from utils.test.extra_data import ExtraDataService -from utils.test.oracle_report_helpers import oracle_report - +from utils.test.node_operators_helpers import RewardDistributionState +from utils.test.oracle_report_helpers import oracle_report, reach_consensus from utils.config import contracts @@ -9,12 +9,19 @@ def extra_data_service(): return ExtraDataService() +@pytest.fixture(scope="module") +def accounting_oracle(interface): + return interface.AccountingOracle(contracts.accounting_oracle) + + +@pytest.fixture +def nor(interface): + return interface.NodeOperatorsRegistry(contracts.node_operators_registry.address) def get_exited_count(node_operator_id): no = contracts.node_operators_registry.getNodeOperator(node_operator_id, False) return no["totalExitedValidators"] - def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): nos_per_item_count = 10 item_count = 2 @@ -32,3 +39,62 @@ def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): extraDataItemsCount=item_count, extraDataList=extra_data.extra_data_list, ) + +def test_accounting_oracle_extra_data_splitted_on_multiple_chunks(extra_data_service, accounting_oracle, nor): + staking_module_id = 1 + max_no_in_payload_count = 3 + max_items_count = 1 + + extra_data = extra_data_service.collect( + {(staking_module_id, i): i for i in range(20, 20 + max_no_in_payload_count)}, + {(staking_module_id, i): get_exited_count(i) for i in range(20, 20 + max_no_in_payload_count)}, + max_items_count, + max_no_in_payload_count, + ) + + assert extra_data.format == 1 + assert extra_data.items_count ==2 + assert len(extra_data.extra_data_list) == 2 + assert len(extra_data.extra_data_hash_list) == 2 + + report = oracle_report( + extraDataFormat=1, + extraDataHashList=extra_data.extra_data_hash_list, + extraDataItemsCount=extra_data.items_count, + extraDataList=extra_data.extra_data_list, + dry_run=True, + ) + + consensusVersion = accounting_oracle.getConsensusVersion() + oracleVersion = accounting_oracle.getContractVersion() + + submitter = reach_consensus( + report.refSlot, + report.hash, + consensusVersion, + contracts.hash_consensus_for_accounting_oracle + ) + + accounting_oracle.submitReportData(report.items, oracleVersion, {"from": submitter}) + + processing_state_after_main_report_submitted = accounting_oracle.getProcessingState() + assert processing_state_after_main_report_submitted["extraDataSubmitted"] == False + assert processing_state_after_main_report_submitted["extraDataItemsCount"] == 2 + assert processing_state_after_main_report_submitted["extraDataItemsSubmitted"] == 0 + assert nor.getRewardDistributionState() == RewardDistributionState.TransferredToModule.value + + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[0], {"from": submitter}) + + processing_state_after_first_extra_data_submitted = accounting_oracle.getProcessingState() + assert processing_state_after_first_extra_data_submitted["extraDataSubmitted"] == False + assert processing_state_after_first_extra_data_submitted["extraDataItemsCount"] == 2 + assert processing_state_after_first_extra_data_submitted["extraDataItemsSubmitted"] == 1 + assert nor.getRewardDistributionState() == RewardDistributionState.TransferredToModule.value + + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[1], {"from": submitter}) + + processing_state_after_second_extra_data_submitted = accounting_oracle.getProcessingState() + assert processing_state_after_second_extra_data_submitted["extraDataSubmitted"] == True + assert processing_state_after_second_extra_data_submitted["extraDataItemsCount"] == 2 + assert processing_state_after_second_extra_data_submitted["extraDataItemsSubmitted"] == 2 + assert nor.getRewardDistributionState() == RewardDistributionState.ReadyForDistribution.value From 49b76d678eac95f6e6b0cd34ebe384af98e4fa2f Mon Sep 17 00:00:00 2001 From: maxim Date: Wed, 7 Aug 2024 19:23:39 +0200 Subject: [PATCH 110/220] test: invalid sort order inside accounting extra data report --- .../test_accounting_oracle_negative.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/acceptance/test_accounting_oracle_negative.py b/tests/acceptance/test_accounting_oracle_negative.py index 05a41f548..3d3f959e3 100644 --- a/tests/acceptance/test_accounting_oracle_negative.py +++ b/tests/acceptance/test_accounting_oracle_negative.py @@ -310,6 +310,34 @@ def test_invalid_extra_data_sort_order(self): ): self.report(extra_data) + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, 1, [1, 3, 2, 4], [1, 1, 1, 1]), + ] + ) + + with reverts( + encode_error( + "InvalidExtraDataSortOrder(uint256)", + [0], + ) + ): + self.report(extra_data) + + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [33, 35, 34, 36], [5000, 5000, 5000, 5000]), + ] + ) + + with reverts( + encode_error( + "InvalidExtraDataSortOrder(uint256)", + [0], + ) + ): + self.report(extra_data) + def test_unexpected_extra_data_item(self, extra_data_service: ExtraDataService) -> None: extra_data = extra_data_service.collect( {(1, 38): 1}, From 7a08e80bcd64e37506d3d88a6c06d44130ac6f72 Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 8 Aug 2024 10:31:01 +0200 Subject: [PATCH 111/220] test: accounting oracle extra data tests 1. deadline missied for second transaction 2. unexpected hash for second transaction --- .../test_accounting_oracle_extra_data.py | 102 ++++++++++++++---- 1 file changed, 79 insertions(+), 23 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data.py b/tests/regression/test_accounting_oracle_extra_data.py index 2be416d57..617fbf8e4 100644 --- a/tests/regression/test_accounting_oracle_extra_data.py +++ b/tests/regression/test_accounting_oracle_extra_data.py @@ -1,9 +1,10 @@ import pytest +from brownie import reverts from utils.test.extra_data import ExtraDataService from utils.test.node_operators_helpers import RewardDistributionState -from utils.test.oracle_report_helpers import oracle_report, reach_consensus +from utils.test.oracle_report_helpers import oracle_report, reach_consensus, wait_to_next_available_report_time from utils.config import contracts - +from utils.evm_script import encode_error @pytest.fixture() def extra_data_service(): @@ -22,25 +23,11 @@ def get_exited_count(node_operator_id): no = contracts.node_operators_registry.getNodeOperator(node_operator_id, False) return no["totalExitedValidators"] -def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): - nos_per_item_count = 10 - item_count = 2 - - extra_data = extra_data_service.collect( - {(1, i): i for i in range(20, 20 + nos_per_item_count)}, - {(1, i): get_exited_count(i) for i in range(20, 20 + nos_per_item_count)}, - item_count, - nos_per_item_count, - ) - - oracle_report( - extraDataFormat=1, - extraDataHashList=extra_data.extra_data_hash_list, - extraDataItemsCount=item_count, - extraDataList=extra_data.extra_data_list, - ) +def assert_modules_reward_distribution_state(expected_state: RewardDistributionState): + assert contracts.node_operators_registry.getRewardDistributionState() == expected_state.value + assert contracts.simple_dvt.getRewardDistributionState() == expected_state.value -def test_accounting_oracle_extra_data_splitted_on_multiple_chunks(extra_data_service, accounting_oracle, nor): +def submit_main_report(accounting_oracle, extra_data_service): staking_module_id = 1 max_no_in_payload_count = 3 max_items_count = 1 @@ -76,12 +63,37 @@ def test_accounting_oracle_extra_data_splitted_on_multiple_chunks(extra_data_ser ) accounting_oracle.submitReportData(report.items, oracleVersion, {"from": submitter}) + assert_modules_reward_distribution_state(RewardDistributionState.TransferredToModule) processing_state_after_main_report_submitted = accounting_oracle.getProcessingState() assert processing_state_after_main_report_submitted["extraDataSubmitted"] == False assert processing_state_after_main_report_submitted["extraDataItemsCount"] == 2 assert processing_state_after_main_report_submitted["extraDataItemsSubmitted"] == 0 - assert nor.getRewardDistributionState() == RewardDistributionState.TransferredToModule.value + + return submitter, extra_data + + +def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): + nos_per_item_count = 10 + item_count = 2 + + extra_data = extra_data_service.collect( + {(1, i): i for i in range(20, 20 + nos_per_item_count)}, + {(1, i): get_exited_count(i) for i in range(20, 20 + nos_per_item_count)}, + item_count, + nos_per_item_count, + ) + + oracle_report( + extraDataFormat=1, + extraDataHashList=extra_data.extra_data_hash_list, + extraDataItemsCount=item_count, + extraDataList=extra_data.extra_data_list, + ) + + +def test_accounting_oracle_extra_data_splitted_on_multiple_chunks(extra_data_service, accounting_oracle, nor): + (submitter, extra_data) = submit_main_report(accounting_oracle, extra_data_service) accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[0], {"from": submitter}) @@ -89,7 +101,7 @@ def test_accounting_oracle_extra_data_splitted_on_multiple_chunks(extra_data_ser assert processing_state_after_first_extra_data_submitted["extraDataSubmitted"] == False assert processing_state_after_first_extra_data_submitted["extraDataItemsCount"] == 2 assert processing_state_after_first_extra_data_submitted["extraDataItemsSubmitted"] == 1 - assert nor.getRewardDistributionState() == RewardDistributionState.TransferredToModule.value + assert_modules_reward_distribution_state(RewardDistributionState.TransferredToModule) accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[1], {"from": submitter}) @@ -97,4 +109,48 @@ def test_accounting_oracle_extra_data_splitted_on_multiple_chunks(extra_data_ser assert processing_state_after_second_extra_data_submitted["extraDataSubmitted"] == True assert processing_state_after_second_extra_data_submitted["extraDataItemsCount"] == 2 assert processing_state_after_second_extra_data_submitted["extraDataItemsSubmitted"] == 2 - assert nor.getRewardDistributionState() == RewardDistributionState.ReadyForDistribution.value + assert_modules_reward_distribution_state(RewardDistributionState.ReadyForDistribution) + + +def test_accounting_oracle_extra_data_miss_deadline(extra_data_service, accounting_oracle, nor): + (submitter, extra_data) = submit_main_report(accounting_oracle, extra_data_service) + + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[0], {"from": submitter}) + + processing_state_after_first_extra_data_submitted = accounting_oracle.getProcessingState() + assert processing_state_after_first_extra_data_submitted["extraDataSubmitted"] == False + assert processing_state_after_first_extra_data_submitted["extraDataItemsCount"] == 2 + assert processing_state_after_first_extra_data_submitted["extraDataItemsSubmitted"] == 1 + assert_modules_reward_distribution_state(RewardDistributionState.TransferredToModule) + + processingDeadlineTime = processing_state_after_first_extra_data_submitted["processingDeadlineTime"] + + wait_to_next_available_report_time(contracts.hash_consensus_for_accounting_oracle) + + with reverts(encode_error("ProcessingDeadlineMissed(uint256)", [processingDeadlineTime])): + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[0], {"from": submitter}) + + with reverts(encode_error("ProcessingDeadlineMissed(uint256)", [processingDeadlineTime])): + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[1], {"from": submitter}) + + +def test_accounting_oracle_extra_data_unexpected_hash(extra_data_service, accounting_oracle): + (submitter, extra_data) = submit_main_report(accounting_oracle, extra_data_service) + + #submit second first extra data tx before first one + with reverts(encode_error("UnexpectedExtraDataHash(bytes32, bytes32)", [str(extra_data.extra_data_hash_list[0]), str(extra_data.extra_data_hash_list[1])])): + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[1], {"from": submitter}) + + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[0], {"from": submitter}) + + # # submit first extra again + with reverts(encode_error("UnexpectedExtraDataHash(bytes32, bytes32)", [str(extra_data.extra_data_hash_list[1]), str(extra_data.extra_data_hash_list[0])])): + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[0], {"from": submitter}) + + accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[1], {"from": submitter}) + + processing_state_after_extra_data_submitted = accounting_oracle.getProcessingState() + assert processing_state_after_extra_data_submitted["extraDataSubmitted"] == True + assert processing_state_after_extra_data_submitted["extraDataItemsCount"] == 2 + assert processing_state_after_extra_data_submitted["extraDataItemsSubmitted"] == 2 + assert_modules_reward_distribution_state(RewardDistributionState.ReadyForDistribution) From 2d2fe3ef262efd71dd87ba7a4158e9646e5a5bf5 Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 8 Aug 2024 10:49:44 +0200 Subject: [PATCH 112/220] test: add addition assert to extra data test --- tests/regression/test_accounting_oracle_extra_data.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/regression/test_accounting_oracle_extra_data.py b/tests/regression/test_accounting_oracle_extra_data.py index 617fbf8e4..438883c71 100644 --- a/tests/regression/test_accounting_oracle_extra_data.py +++ b/tests/regression/test_accounting_oracle_extra_data.py @@ -93,7 +93,9 @@ def test_accounting_oracle_too_node_ops_per_extra_data_item(extra_data_service): def test_accounting_oracle_extra_data_splitted_on_multiple_chunks(extra_data_service, accounting_oracle, nor): - (submitter, extra_data) = submit_main_report(accounting_oracle, extra_data_service) + (submitter, extra_data) = submit_main_report(accounting_oracle, extra_data_service) + + assert_modules_reward_distribution_state(RewardDistributionState.TransferredToModule) accounting_oracle.submitReportExtraDataList(extra_data.extra_data_list[0], {"from": submitter}) From de2a91eba043ef58ba52a87669a46f4c51dea21c Mon Sep 17 00:00:00 2001 From: skhomuti Date: Mon, 12 Aug 2024 14:43:58 +0500 Subject: [PATCH 113/220] - fix csverifier - fix target share distribution test --- interfaces/csm/CSVerifier.json | 26 +++++++------- tests/acceptance/test_csm.py | 3 +- .../test_staking_router_stake_distribution.py | 36 +++++++++---------- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/interfaces/csm/CSVerifier.json b/interfaces/csm/CSVerifier.json index ec30f8974..4b1c3515f 100644 --- a/interfaces/csm/CSVerifier.json +++ b/interfaces/csm/CSVerifier.json @@ -3,7 +3,7 @@ "type": "constructor", "inputs": [ { - "name": "locator", + "name": "withdrawalAddress", "type": "address", "internalType": "address" }, @@ -166,52 +166,52 @@ }, { "type": "function", - "name": "LOCATOR", + "name": "MODULE", "inputs": [], "outputs": [ { "name": "", "type": "address", - "internalType": "contract ILidoLocator" + "internalType": "contract ICSModule" } ], "stateMutability": "view" }, { "type": "function", - "name": "MODULE", + "name": "PIVOT_SLOT", "inputs": [], "outputs": [ { "name": "", - "type": "address", - "internalType": "contract ICSModule" + "type": "uint64", + "internalType": "Slot" } ], "stateMutability": "view" }, { "type": "function", - "name": "PIVOT_SLOT", + "name": "SLOTS_PER_EPOCH", "inputs": [], "outputs": [ { "name": "", "type": "uint64", - "internalType": "Slot" + "internalType": "uint64" } ], "stateMutability": "view" }, { "type": "function", - "name": "SLOTS_PER_EPOCH", + "name": "WITHDRAWAL_ADDRESS", "inputs": [], "outputs": [ { "name": "", - "type": "uint64", - "internalType": "uint64" + "type": "address", + "internalType": "address" } ], "stateMutability": "view" @@ -700,12 +700,12 @@ }, { "type": "error", - "name": "ZeroLocatorAddress", + "name": "ZeroModuleAddress", "inputs": [] }, { "type": "error", - "name": "ZeroModuleAddress", + "name": "ZeroWithdrawalAddress", "inputs": [] } ] diff --git a/tests/acceptance/test_csm.py b/tests/acceptance/test_csm.py index fd1609461..7d8a4b107 100644 --- a/tests/acceptance/test_csm.py +++ b/tests/acceptance/test_csm.py @@ -8,6 +8,7 @@ LIDO_LOCATOR, LIDO, WITHDRAWAL_QUEUE, + WITHDRAWAL_VAULT, WSTETH_TOKEN, STAKING_ROUTER, AGENT, @@ -192,7 +193,7 @@ def test_early_adoption_state(early_adoption): assert early_adoption.CURVE_ID() == 1 def test_verifier_state(verifier): - assert verifier.LOCATOR() == LIDO_LOCATOR + assert verifier.WITHDRAWAL_ADDRESS() == WITHDRAWAL_VAULT assert verifier.MODULE() == CSM_ADDRESS assert verifier.SLOTS_PER_EPOCH() == CHAIN_SLOTS_PER_EPOCH # TODO uncomment this when values are known diff --git a/tests/regression/test_staking_router_stake_distribution.py b/tests/regression/test_staking_router_stake_distribution.py index 9c669f7dd..39f5ab6ed 100644 --- a/tests/regression/test_staking_router_stake_distribution.py +++ b/tests/regression/test_staking_router_stake_distribution.py @@ -147,14 +147,14 @@ def test_target_share_distribution(stranger): min_target_share = 1 # 0.01% = 1 / 10000 nor_m_id = 1 nor_m = modules[nor_m_id] - sdvt_m_id = 2 - sdvt_m = modules[sdvt_m_id] cur_total_active_keys = prep_modules_info(modules) + module = sorted(modules.values(), key=lambda m: m.active_keys / cur_total_active_keys * TOTAL_BASIS_POINTS)[0] + # calc some hypothetical module allocation share for testing - expected_active_keys_1 = sdvt_m.active_keys + keys_to_allocate - expected_active_keys_2 = sdvt_m.active_keys + keys_to_allocate_double + expected_active_keys_1 = module.active_keys + keys_to_allocate + expected_active_keys_2 = module.active_keys + keys_to_allocate_double expected_total_active_keys = cur_total_active_keys + keys_to_allocate expected_total_active_keys_2 = cur_total_active_keys + keys_to_allocate_double @@ -169,42 +169,42 @@ def test_target_share_distribution(stranger): assert expected_target_share_2 > expected_target_share_1 # force update module `targetShare` value to simulate new allocation - sdvt_m.target_share = expected_target_share_1 + module.target_share = expected_target_share_1 expected_total_allocated_keys, expected_total_active_keys = calc_allocation(modules, keys_to_allocate, True) assert expected_total_allocated_keys == keys_to_allocate - assert sdvt_m.active_keys >= expected_active_keys_1 - assert sdvt_m.allocated_keys == keys_to_allocate + assert module.active_keys >= expected_active_keys_1 + assert module.allocated_keys == keys_to_allocate assert nor_m.allocated_keys == 0 expected_total_allocated_keys, expected_total_active_keys = calc_allocation(modules, keys_to_allocate_double, True) assert expected_total_allocated_keys == keys_to_allocate_double - assert sdvt_m.active_keys < expected_active_keys_2 - assert sdvt_m.allocated_keys < keys_to_allocate_double + assert module.active_keys < expected_active_keys_2 + assert module.allocated_keys < keys_to_allocate_double assert nor_m.allocated_keys <= keys_to_allocate_double # aet the new target share value, which will be reached after 1s deposit of `keys_to_allocate`` batch contracts.staking_router.updateStakingModule( - sdvt_m_id, + module.id, expected_target_share_1, - sdvt_m.priorityExitShareThreshold, - sdvt_m.module_fee, - sdvt_m.treasury_fee, - sdvt_m.maxDepositsPerBlock, - sdvt_m.minDepositBlockDistance, + module.priorityExitShareThreshold, + module.module_fee, + module.treasury_fee, + module.maxDepositsPerBlock, + module.minDepositBlockDistance, {"from": contracts.agent}, ) # add enough depositable keys to the target module to overcome the target share # at least first 3 NOs, each with 1/3 of the `keys_to_allocate_double` available keys - fill_simple_dvt_ops_vetted_keys(stranger, 3, (sdvt_m.deposited_keys + keys_to_allocate_double + 3) // 3) + fill_simple_dvt_ops_vetted_keys(stranger, 3, (module.deposited_keys + keys_to_allocate_double + 3) // 3) # update the modules info and recalc the allocation according to the module limits modules = get_modules_info(contracts.staking_router) expected_total_allocated_keys, expected_total_active_keys = calc_allocation(modules, keys_to_allocate_double, False) assert expected_total_allocated_keys == keys_to_allocate_double - assert sdvt_m.active_keys < expected_active_keys_2 - assert sdvt_m.allocated_keys < keys_to_allocate_double + assert module.active_keys < expected_active_keys_2 + assert module.allocated_keys < keys_to_allocate_double assert nor_m.allocated_keys <= keys_to_allocate_double allocation_from_contract = contracts.staking_router.getDepositsAllocation(keys_to_allocate_double) From 67f3e5db21cc8ebffe33ed1afc30d5cd8b373ac1 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Wed, 14 Aug 2024 18:03:47 +0500 Subject: [PATCH 114/220] - add a bunch of csm regression tests --- tests/regression/conftest.py | 5 + .../test_accounting_oracle_extra_data.py | 4 - ...accounting_oracle_extra_data_full_items.py | 5 - tests/regression/test_csm.py | 220 ++++++++++++++++++ tests/regression/test_dsm_keys_unvetting.py | 43 +--- tests/regression/test_sanity_checks.py | 6 - .../test_staking_router_stake_distribution.py | 19 +- utils/dsm.py | 29 +++ utils/test/csm_helpers.py | 51 ++++ 9 files changed, 328 insertions(+), 54 deletions(-) create mode 100644 tests/regression/test_csm.py create mode 100644 utils/test/csm_helpers.py diff --git a/tests/regression/conftest.py b/tests/regression/conftest.py index d849fc318..099afb95a 100644 --- a/tests/regression/conftest.py +++ b/tests/regression/conftest.py @@ -3,6 +3,7 @@ from utils.config import contracts from utils.import_current_votes import is_there_any_vote_scripts, is_there_any_upgrade_scripts, start_and_execute_votes +from utils.test.extra_data import ExtraDataService from utils.test.helpers import ETH from utils.test.oracle_report_helpers import oracle_report @@ -25,3 +26,7 @@ def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger): if os.getenv(ENV_REPORT_AFTER_VOTE): oracle_report(cl_diff=ETH(523), exclude_vaults_balances=False) + +@pytest.fixture() +def extra_data_service() -> ExtraDataService: + return ExtraDataService() diff --git a/tests/regression/test_accounting_oracle_extra_data.py b/tests/regression/test_accounting_oracle_extra_data.py index 438883c71..37e36514a 100644 --- a/tests/regression/test_accounting_oracle_extra_data.py +++ b/tests/regression/test_accounting_oracle_extra_data.py @@ -1,14 +1,10 @@ import pytest from brownie import reverts -from utils.test.extra_data import ExtraDataService from utils.test.node_operators_helpers import RewardDistributionState from utils.test.oracle_report_helpers import oracle_report, reach_consensus, wait_to_next_available_report_time from utils.config import contracts from utils.evm_script import encode_error -@pytest.fixture() -def extra_data_service(): - return ExtraDataService() @pytest.fixture(scope="module") def accounting_oracle(interface): diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 34d0e842f..260613757 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -4,7 +4,6 @@ from brownie.network.web3 import Web3 from utils.test.deposits_helpers import fill_deposit_buffer -from utils.test.extra_data import ExtraDataService from utils.test.helpers import shares_balance, almostEqWithDiff from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch from utils.test.oracle_report_helpers import oracle_report @@ -14,10 +13,6 @@ from utils.config import contracts from utils.test.simple_dvt_helpers import simple_dvt_add_node_operators, simple_dvt_add_keys, simple_dvt_vet_keys -@pytest.fixture() -def extra_data_service(): - return ExtraDataService() - @pytest.fixture def voting_eoa(accounts): diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py new file mode 100644 index 000000000..7b7dfd7a6 --- /dev/null +++ b/tests/regression/test_csm.py @@ -0,0 +1,220 @@ +import pytest + +from brownie import reverts, web3 + +from utils.config import ( + contracts, + ContractsLazyLoader, +) +from utils.dsm import UnvetArgs, to_bytes, set_single_guardian +from utils.evm_script import encode_error +from utils.test.csm_helpers import csm_add_node_operator, get_ea_member, csm_upload_keys +from utils.test.deposits_helpers import fill_deposit_buffer +from utils.test.helpers import ETH +from utils.test.oracle_report_helpers import oracle_report +from utils.test.staking_router_helpers import set_staking_module_status, StakingModuleStatus + +contracts: ContractsLazyLoader = contracts + +CSM_MODULE_ID = 3 + + +@pytest.fixture(scope="module") +def csm(): + return contracts.csm + + +@pytest.fixture(scope="module") +def accounting(): + return contracts.cs_accounting + + +@pytest.fixture(scope="module") +def fee_distributor(): + return contracts.cs_fee_distributor + + +@pytest.fixture() +def node_operator(csm, accounting) -> int: + address, proof = get_ea_member() + return csm_add_node_operator(csm, accounting, address, proof) + + +@pytest.fixture() +def pause_modules(): + # pause deposit to all modules except csm + # to be sure that all deposits go to csm + modules = contracts.staking_router.getStakingModules() + for module in modules: + if module[0] != CSM_MODULE_ID: + set_staking_module_status(module[0], StakingModuleStatus.Stopped) + + +@pytest.fixture() +def deposits_to_csm(csm, pause_modules, node_operator): + (_, _, depositable) = csm.getStakingModuleSummary() + fill_deposit_buffer(depositable) + contracts.lido.deposit(depositable, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module}) + + +@pytest.mark.usefixtures("pause_modules") +def test_deposit(node_operator, csm): + (_, _, depositable_validators_count) = csm.getStakingModuleSummary() + deposits_count = depositable_validators_count + fill_deposit_buffer(deposits_count) + + contracts.lido.deposit(deposits_count, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module}) + + no = csm.getNodeOperator(node_operator) + assert no["totalDepositedKeys"] == no["totalAddedKeys"] + + +@pytest.mark.usefixtures("deposits_to_csm") +def test_mint_rewards_happy_path(csm, fee_distributor): + csm_shares_before = contracts.lido.sharesOf(csm) + fee_distributor_shares_before = contracts.lido.sharesOf(fee_distributor) + + oracle_report(cl_diff=ETH(1)) + + assert csm_shares_before == contracts.lido.sharesOf(csm) + assert contracts.lido.sharesOf(fee_distributor) > fee_distributor_shares_before + + +def test_csm_target_limits(csm, node_operator): + target_limit_mode = 1 + target_limit = 2 + contracts.staking_router.updateTargetValidatorsLimits( + CSM_MODULE_ID, + node_operator, + target_limit_mode, + target_limit, + {"from": contracts.agent} + ) + + no = csm.getNodeOperator(node_operator) + assert no["targetLimitMode"] == target_limit_mode + assert no["targetLimit"] == target_limit + + +def test_csm_update_refunded(node_operator): + refunded_validators_count = 1 + with reverts(encode_error("NotSupported()")): + contracts.staking_router.updateRefundedValidatorsCount( + CSM_MODULE_ID, + node_operator, + refunded_validators_count, + {"from": contracts.agent} + ) + + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_report_exited(csm, node_operator, extra_data_service): + exited_keys = 5 + extra_data = extra_data_service.collect({}, {(CSM_MODULE_ID, node_operator): exited_keys}, exited_keys, exited_keys) + oracle_report( + extraDataFormat=1, + extraDataHashList=extra_data.extra_data_hash_list, + extraDataItemsCount=1, + extraDataList=extra_data.extra_data_list, + stakingModuleIdsWithNewlyExitedValidators=[CSM_MODULE_ID], + numExitedValidatorsByStakingModule=[1], + ) + + no = csm.getNodeOperator(node_operator) + assert no["totalExitedKeys"] == exited_keys + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_report_stuck(csm, node_operator, extra_data_service): + stuck_keys = 5 + extra_data = extra_data_service.collect( {(CSM_MODULE_ID, node_operator): stuck_keys}, {}, stuck_keys, stuck_keys) + oracle_report( + extraDataFormat=1, + extraDataHashList=extra_data.extra_data_hash_list, + extraDataItemsCount=1, + extraDataList=extra_data.extra_data_list, + stakingModuleIdsWithNewlyExitedValidators=[CSM_MODULE_ID], + numExitedValidatorsByStakingModule=[1], + ) + + no = csm.getNodeOperator(node_operator) + assert no["stuckValidatorsCount"] == stuck_keys + + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_get_staking_module_summary(csm, accounting, node_operator, extra_data_service): + (exited_before, deposited_before, depositable_before) = contracts.staking_router.getStakingModuleSummary(CSM_MODULE_ID) + + # Assure there are new exited keys + exited_keys = 5 + extra_data = extra_data_service.collect({}, {(CSM_MODULE_ID, node_operator): exited_keys}, exited_keys, exited_keys) + oracle_report( + extraDataFormat=1, + extraDataHashList=extra_data.extra_data_hash_list, + extraDataItemsCount=1, + extraDataList=extra_data.extra_data_list, + stakingModuleIdsWithNewlyExitedValidators=[CSM_MODULE_ID], + numExitedValidatorsByStakingModule=[1], + ) + + # Assure there are new deposited keys + + deposits_count = 3 + new_keys = 5 + new_depositable = new_keys - deposits_count + address, _ = get_ea_member() + csm_upload_keys(csm, accounting, node_operator, address, new_keys) + fill_deposit_buffer(deposits_count) + contracts.lido.deposit(deposits_count, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module}) + + (exited_after, deposited_after, depositable_after) = contracts.staking_router.getStakingModuleSummary(CSM_MODULE_ID) + + assert exited_after == exited_before + exited_keys + assert deposited_after == deposited_before + deposits_count + assert depositable_after == depositable_before + new_depositable + + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_get_node_operator_summary(csm, node_operator, extra_data_service): + exited_keys = 1 + stuck_keys = 1 + extra_data = extra_data_service.collect({(CSM_MODULE_ID, node_operator): stuck_keys}, {(CSM_MODULE_ID, node_operator): exited_keys}, 2, 2) + oracle_report( + extraDataFormat=1, + extraDataHashList=extra_data.extra_data_hash_list, + extraDataItemsCount=2, + extraDataList=extra_data.extra_data_list, + stakingModuleIdsWithNewlyExitedValidators=[CSM_MODULE_ID], + numExitedValidatorsByStakingModule=[1], + ) + + summary = contracts.staking_router.getNodeOperatorSummary(CSM_MODULE_ID, node_operator) + assert summary["targetLimitMode"] == 0 + assert summary["targetValidatorsCount"] == 0 + assert summary["stuckValidatorsCount"] == stuck_keys + assert summary["refundedValidatorsCount"] == 0 + assert summary["stuckPenaltyEndTimestamp"] == 0 + assert summary["totalExitedValidators"] == exited_keys + assert summary["totalDepositedValidators"] == 5 + assert summary["depositableValidatorsCount"] == 0 + + +def test_csm_decrease_vetted_keys(csm, node_operator, stranger): + block_number = web3.eth.get_block_number() + block = web3.eth.get_block(block_number) + staking_module_nonce = contracts.staking_router.getStakingModuleNonce(CSM_MODULE_ID) + unvet_args = UnvetArgs( + block_number=block_number, + block_hash=block.hash, + staking_module_id=CSM_MODULE_ID, + nonce=staking_module_nonce, + node_operator_ids=to_bytes(node_operator, 16), + vetted_signing_keys_counts=to_bytes(1, 32), + ) + + set_single_guardian(contracts.deposit_security_module, contracts.agent, stranger) + + contracts.deposit_security_module.unvetSigningKeys(*unvet_args.to_tuple(), (0, 0), {"from": stranger.address}) + + no = csm.getNodeOperator(node_operator) + assert no["totalVettedKeys"] == 1 + diff --git a/tests/regression/test_dsm_keys_unvetting.py b/tests/regression/test_dsm_keys_unvetting.py index 3e24964bc..9bc90d755 100644 --- a/tests/regression/test_dsm_keys_unvetting.py +++ b/tests/regression/test_dsm_keys_unvetting.py @@ -6,24 +6,13 @@ DSM_MAX_OPERATORS_PER_UNVETTING, NODE_OPERATORS_REGISTRY, ) -from utils.dsm import DSMUnvetMessage, UnvetArgs +from utils.dsm import DSMUnvetMessage, UnvetArgs, to_bytes, set_single_guardian from utils.evm_script import encode_error -from typing import Tuple from utils.staking_module import add_node_operator from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch STAKING_MODULE_ID = 1 -def get_unvet_args(overriding_args: UnvetArgs) -> Tuple[int, str, int, int, str, str]: - block_number = overriding_args.block_number - block_hash = overriding_args.block_hash - staking_module_id = overriding_args.staking_module_id - nonce = overriding_args.nonce - node_operator_ids = overriding_args.node_operator_ids - vetted_signing_keys_counts = overriding_args.vetted_signing_keys_counts - - return block_number, block_hash, staking_module_id, nonce, node_operator_ids, vetted_signing_keys_counts - @pytest.fixture(scope="module") def dsm() -> interface.DepositSecurityModule: return contracts.deposit_security_module @@ -40,24 +29,6 @@ def agent(accounts): def new_guardian(accounts): return accounts[9] -def set_single_guardian(dsm, agent, new_guardian): - guardians = dsm.getGuardians() - dsm.addGuardian(new_guardian.address, 1, {"from": agent}) - - for guardian in guardians: - dsm.removeGuardian(guardian, 1, {"from": agent}) - - assert len(dsm.getGuardians()) == 1 - assert dsm.isGuardian(new_guardian.address) - -def to_bytes(number: int, final_length: int) -> str: - hex_string = format(number, 'x') - num_of_leading_zeroes_needed = final_length - len(hex_string) - - return bytes.fromhex( - '0' * num_of_leading_zeroes_needed + hex_string if num_of_leading_zeroes_needed > 0 else hex_string - ) - def test_dsm_max_operators_per_unvetting(dsm, agent, stranger): assert dsm.getMaxOperatorsPerUnvetting() == DSM_MAX_OPERATORS_PER_UNVETTING @@ -75,14 +46,14 @@ def test_dsm_keys_unvetting_by_stranger_without_guardian_sign(dsm, stranger): block = web3.eth.get_block(block_number) staking_module_nonce = contracts.staking_router.getStakingModuleNonce(1) - args = get_unvet_args(UnvetArgs( + args = UnvetArgs( block_number=block_number, block_hash=block.hash, staking_module_id=staking_module_id, nonce=staking_module_nonce, node_operator_ids=to_bytes(operator_id, 16), vetted_signing_keys_counts=to_bytes(1, 32), - )) + ).to_tuple() non_guardian_private_key="0x" + "1" * 64 @@ -107,14 +78,14 @@ def test_dsm_keys_unvetting_by_stranger_with_guardian_sign(dsm, agent, stranger) block = web3.eth.get_block(block_number) staking_module_nonce = contracts.staking_router.getStakingModuleNonce(1) - args = get_unvet_args(UnvetArgs( + args = UnvetArgs( block_number=block_number, block_hash=block.hash, staking_module_id=staking_module_id, nonce=staking_module_nonce, node_operator_ids=to_bytes(operator_id, 16), vetted_signing_keys_counts=to_bytes(1, 32), - )) + ).to_tuple() DSMUnvetMessage.set_message_prefix(dsm.UNVET_MESSAGE_PREFIX()) valid_unvet_message = DSMUnvetMessage(*args) @@ -149,7 +120,7 @@ def test_dsm_keys_unvetting_by_guardian(dsm, agent, stranger): set_single_guardian(dsm, agent, new_guardian) - dsm.unvetSigningKeys(*get_unvet_args(unvet_args), (0, 0), {"from": new_guardian.address}) + dsm.unvetSigningKeys(*unvet_args.to_tuple(), (0, 0), {"from": new_guardian.address}) node_operator_after_unvetting = staking_module.getNodeOperator(operator_id, True) assert node_operator_after_unvetting["totalDepositedValidators"] == totalDepositedValidators @@ -201,7 +172,7 @@ def test_dsm_decrease_vetted_signing_keys_count(dsm, agent, voting, stranger): new_guardian = stranger set_single_guardian(dsm, agent, new_guardian) - dsm.unvetSigningKeys(*get_unvet_args(unvet_args), (0, 0), {"from": new_guardian.address}) + dsm.unvetSigningKeys(*unvet_args.to_tuple(), (0, 0), {"from": new_guardian.address}) node_operator_after_unvetting = staking_module.getNodeOperator(operator_id, True) assert node_operator_after_unvetting["totalVettedValidators"] == vetted_signing_keys_counts_after_unvet diff --git a/tests/regression/test_sanity_checks.py b/tests/regression/test_sanity_checks.py index 53cbde3c2..4114d16f3 100644 --- a/tests/regression/test_sanity_checks.py +++ b/tests/regression/test_sanity_checks.py @@ -1,7 +1,6 @@ import pytest from brownie import web3, reverts, accounts, chain # type: ignore from utils.test.exit_bus_data import LidoValidator -from utils.test.extra_data import ExtraDataService from utils.test.oracle_report_helpers import ( oracle_report, prepare_exit_bus_report, @@ -39,11 +38,6 @@ def first_report(): oracle_report(silent=True) -@pytest.fixture() -def extra_data_service(): - return ExtraDataService() - - def test_cant_report_more_validators_than_deposited(): (deposited, clValidators, _) = contracts.lido.getBeaconStat() with reverts("REPORTED_MORE_DEPOSITED"): diff --git a/tests/regression/test_staking_router_stake_distribution.py b/tests/regression/test_staking_router_stake_distribution.py index 39f5ab6ed..de1174ced 100644 --- a/tests/regression/test_staking_router_stake_distribution.py +++ b/tests/regression/test_staking_router_stake_distribution.py @@ -1,6 +1,7 @@ from typing import Dict from utils.config import contracts +from utils.test.csm_helpers import csm_add_node_operator, get_ea_member from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.simple_dvt_helpers import fill_simple_dvt_ops_vetted_keys from utils.test.staking_router_helpers import StakingModuleStatus @@ -102,12 +103,24 @@ def calc_allocation(modules: Dict[int, Module], keys_to_allocate: int, ignore_de return total_allocated_keys, target_total_active_keys -def test_stake_distribution(): +def assure_depositable_keys(stranger): + modules = get_modules_info(contracts.staking_router) + if not modules[1].depositable_keys: + pass + if not modules[2].depositable_keys: + fill_simple_dvt_ops_vetted_keys(stranger, 3, 5) + if not modules[3].depositable_keys: + address, proof = get_ea_member() + csm_add_node_operator(contracts.csm, contracts.cs_accounting, address, proof) + +def test_stake_distribution(stranger): """ Test stake distribution among the staking modules 1. checks that result of `getDepositsAllocation` matches the local allocation calculations 2. checks that deposits to modules can be made according to the calculated allocation """ + assure_depositable_keys(stranger) + keys_to_allocate = 100 # keys to allocate to the modules allocation_from_contract = contracts.staking_router.getDepositsAllocation(keys_to_allocate) @@ -123,8 +136,8 @@ def test_stake_distribution(): # perform deposits to the modules for module in modules.values(): - if module.allocated_keys > 0: - contracts.lido.deposit(module.allocated_keys, module.id, "0x", {"from": contracts.deposit_security_module}) + assert module.allocated_keys > 0 + contracts.lido.deposit(module.allocated_keys, module.id, "0x", {"from": contracts.deposit_security_module}) # check that the new active keys in the modules match the expected values module_digests_after_deposit = contracts.staking_router.getAllStakingModuleDigests() diff --git a/utils/dsm.py b/utils/dsm.py index 5874c3381..044c0d032 100644 --- a/utils/dsm.py +++ b/utils/dsm.py @@ -15,6 +15,16 @@ class UnvetArgs: node_operator_ids: bytes = None vetted_signing_keys_counts: bytes = None + def to_tuple(self): + return ( + self.block_number, + self.block_hash, + self.staking_module_id, + self.nonce, + self.node_operator_ids, + self.vetted_signing_keys_counts + ) + class DSMMessage: MESSAGE_PREFIX: str = "" @@ -82,3 +92,22 @@ def to_eip2098(signedMessage: SignedMessage) -> Dict[str, Any]: raise ValueError("invalid signature 's' value") vs[0] |= (v % 27) << 7 # set the first bit of vs to the v parity bit return (r_bytes, bytes(vs)) + + +def to_bytes(number: int, final_length: int) -> str: + hex_string = format(number, 'x') + num_of_leading_zeroes_needed = final_length - len(hex_string) + + return bytes.fromhex( + '0' * num_of_leading_zeroes_needed + hex_string if num_of_leading_zeroes_needed > 0 else hex_string + ) + +def set_single_guardian(dsm, agent, new_guardian): + guardians = dsm.getGuardians() + dsm.addGuardian(new_guardian.address, 1, {"from": agent}) + + for guardian in guardians: + dsm.removeGuardian(guardian, 1, {"from": agent}) + + assert len(dsm.getGuardians()) == 1 + assert dsm.isGuardian(new_guardian.address) diff --git a/utils/test/csm_helpers.py b/utils/test/csm_helpers.py new file mode 100644 index 000000000..56f23b67d --- /dev/null +++ b/utils/test/csm_helpers.py @@ -0,0 +1,51 @@ +from brownie import ZERO_ADDRESS + +from utils.balance import set_balance +from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch + + +def get_ea_member(): + """ + Random address and proof for EA member + """ + address = set_balance("0x00200f4e638e81ebe172daa18c9193a33a50bbbd", 100000) + proof = ["0x6afc021ded39a008e9e7c646cd70b0e0425b8c0cc2decc102d45a09a9cadc3b4", + "0x9fb8ad314dcef15562b7a930e037068f77bb860156199862df2957017d68b59b", + "0xa70999dbf9fb0843abbcfbc67498e195527ac129b43994dfaccdde3479893bed", + "0xe529a4c4315a65bc576d6cb030bb0f6957084d18fb108d8bb2d2b9ac05b17d66", + "0xc94fe8c075792d6610715e8adbc53fafd06aeddaeb4fcb45867d8ab92685bbe6", + "0xb2cc15dba514f0df05e7243a48aa47b1a5455f5a4291398c0edacca5f0aca2fc", + "0x7c4efc55c91a8f3b6064dcdb0622d9815dc31998fc6f9069a6ba0188512f1144", + "0xcb497013c0ad8e40663b8318967dcbc1cfbb38132a5bb36a6def0bf1352b3733", + "0xab3d7faaf4662097e8a953ee63af9e71078a4224c4c69425b6c53404aa14459f", + "0x9e1485ad05559cc88dc80939a490c03bbdb7aa81c01b259023c7cdc73884dabc", + "0x6206a54be4267fcced2b6c60e90b9f1974933b4655444a56ae993d4727bacde4", + "0x60aaa2f08de8edbe2b9edfb201c5ed962cbbd8ce1d096013549fc4de2dc330d6", + "0xd88ad1a0d41adf346661f16fad68e45102a5f7730122af03c81bdc90a6b473d7", + "0x9abd3efc8d538c4714dae174a75caaa1414c9a9155e8cea71e977822978807df"] + return address, proof + + +def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5): + pubkeys_batch = random_pubkeys_batch(keys_count) + signatures_batch = random_signatures_batch(keys_count) + curve_id = 1 # EA curve + csm.addNodeOperatorETH( + keys_count, + pubkeys_batch, + signatures_batch, + (ZERO_ADDRESS, ZERO_ADDRESS, False), + proof, + ZERO_ADDRESS, + {"from": node_operator, "value": accounting.getBondAmountByKeysCount['uint256,uint256'](keys_count, curve_id)} + ) + + return csm.getNodeOperatorsCount() - 1 + + +def csm_upload_keys(csm, accounting, no_id, node_operator, keys_count=5): + pubkeys_batch = random_pubkeys_batch(keys_count) + signatures_batch = random_signatures_batch(keys_count) + csm.addValidatorKeysETH(no_id, keys_count, pubkeys_batch, signatures_batch, + {"from": node_operator, "value": accounting.getRequiredBondForNextKeys(no_id, keys_count)} + ) From 27ba48a882975d8e8395898ea605401be8ec9c77 Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 5 Sep 2024 17:33:06 +0200 Subject: [PATCH 115/220] feat: update maxNodeOperatorsPerExtraDataItemCount Update limit according to latest estimation of gas consumption in CSM module --- configs/config_mainnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 31deca0da..6becd69c3 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -185,7 +185,7 @@ SIMULATED_SHARE_RATE_DEVIATION_BP_LIMIT = 50 # 0.5% MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT = 600 MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION = 8 -MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM = 62 +MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM = 24 REQUEST_TIMESTAMP_MARGIN = 7680 # 2 hours rounded to epoch length MAX_POSITIVE_TOKEN_REBASE = 750000 INITIAL_SLASHING_AMOUNT_PWEI = 1000 From 1755465ad2779cd98e272ddea35a0eaef5a07171 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 30 Sep 2024 20:52:22 +0400 Subject: [PATCH 116/220] fix: parameters --- scripts/vote_sr_v2.py | 47 ++++++++++++++++++++++++---------------- tests/test_vote_sr_v2.py | 12 ++++++---- utils/easy_track.py | 30 ++++++++++--------------- 3 files changed, 48 insertions(+), 41 deletions(-) diff --git a/scripts/vote_sr_v2.py b/scripts/vote_sr_v2.py index 48250f6fd..006f01680 100644 --- a/scripts/vote_sr_v2.py +++ b/scripts/vote_sr_v2.py @@ -12,8 +12,8 @@ 10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo 11. Update `SimpleDVT` implementation 12. Finalize SimpleDVT upgrade -13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}`, -14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}`, +13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}` +14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}` 15. Grant manage consensus role to agent ${AGENT}` 16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` 17. Revoke manage consensus role from agent ${AGENT} @@ -60,7 +60,12 @@ add_implementation_to_sdvt_app_repo, ) from utils.permissions import encode_oz_grant_role, encode_oz_revoke_role -from utils.easy_track import add_evmscript_factory, create_permissions, create_permissions_for_overloaded_method, remove_evmscript_factory +from utils.easy_track import ( + add_evmscript_factory, + create_permissions, + create_permissions_for_overloaded_method, + remove_evmscript_factory, +) from utils.kernel import update_app_implementation from utils.voting import bake_vote_items, confirm_vote_script, create_vote @@ -72,17 +77,12 @@ ## Easy track OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" # !!!! that is locally deployed factory address, before run set contract address here -NEW_TARGET_LIMIT_FACTORY = "0x00B0517de6b2b09aBD3a7B69d66D85eFdb2c7d94" - -## SR -PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [10_000, 10_000] -MAX_DEPOSITS_PER_BLOCK = [50, 50] -MIN_DEPOSIT_BLOCK_DISTANCES = [25, 25] +NEW_TARGET_LIMIT_FACTORY = "0x8a6E9a8E0bB561f8cdAb1619ECc4585aaF126D73" ## Curated module nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" -CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 -CURATED_MAX_DEPOSITS_PER_BLOCK = 50 +CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10_000 +CURATED_MAX_DEPOSITS_PER_BLOCK = 150 CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 NOR_VERSION_REPO = ["5", "0", "0"] @@ -91,11 +91,16 @@ ## SDVT module sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" -SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 10000 -SDVT_MAX_DEPOSITS_PER_BLOCK = 50 +SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 400 +SDVT_MAX_DEPOSITS_PER_BLOCK = 150 SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 SDVT_VERSION_REPO = ["2", "0", "0"] +## SR +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS] +MAX_DEPOSITS_PER_BLOCK = [CURATED_MAX_DEPOSITS_PER_BLOCK, SDVT_MAX_DEPOSITS_PER_BLOCK] +MIN_DEPOSIT_BLOCK_DISTANCES = [CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, SDVT_MIN_DEPOSIT_BLOCK_DISTANCES] + ## Accounting oracle AO_CONSENSUS_VERSION = 2 ## Vebo @@ -104,14 +109,14 @@ # CSM ## Easy track # !!!! that is locally deployed factory address, before run set contract address here -EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xd2983525E903Ef198d5dD0777712EB66680463bc" +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0x2963ff0196a901ec3F56d7531e7C4Ce8F226462B" ## Parameters CS_MODULE_NAME = "Community Staking" -CS_STAKE_SHARE_LIMIT = 2000 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 2500 -CS_STAKING_MODULE_FEE = 800 -CS_TREASURY_FEE = 200 +CS_STAKE_SHARE_LIMIT = 100 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 100 +CS_STAKING_MODULE_FEE = 600 +CS_TREASURY_FEE = 400 CS_MAX_DEPOSITS_PER_BLOCK = 30 CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 CS_ORACLE_INITIAL_EPOCH = 58050 @@ -303,7 +308,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T "19. Add Target limit for SDVT factory to ET", add_evmscript_factory( factory=NEW_TARGET_LIMIT_FACTORY, - permissions=(create_permissions_for_overloaded_method(contracts.simple_dvt, "updateTargetValidatorsLimits", ('uint', 'uint', 'uint'))), + permissions=( + create_permissions_for_overloaded_method( + contracts.simple_dvt, "updateTargetValidatorsLimits", ("uint", "uint", "uint") + ) + ), ), ), # diff --git a/tests/test_vote_sr_v2.py b/tests/test_vote_sr_v2.py index 847004e43..42b80b184 100644 --- a/tests/test_vote_sr_v2.py +++ b/tests/test_vote_sr_v2.py @@ -14,7 +14,7 @@ CS_ACCOUNTING_ADDRESS, CSM_ADDRESS, ) -from scripts.mainnet.vote_sr_v2_mainnet import ( +from scripts.vote_sr_v2 import ( start_vote, # oracles AO_CONSENSUS_VERSION, @@ -59,7 +59,7 @@ validate_evmscript_factory_removed_event, EVMScriptFactoryAdded, ) -from utils.easy_track import create_permissions +from utils.easy_track import create_permissions, create_permissions_overloaded # Impl addresses before vote OLD_LOCATOR_IMPL_ADDRESS = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" @@ -120,7 +120,7 @@ class StakingModuleItem(NamedTuple): "stakingModuleAddress": SIMPLE_DVT, "stakingModuleFee": 800, "treasuryFee": 200, - "targetShare": 50, + "targetShare": 400, "priorityExitShareThreshold": None, "maxDepositsPerBlock": None, "minDepositBlockDistance": None, @@ -333,7 +333,11 @@ def test_vote( events[18], EVMScriptFactoryAdded( factory_addr=NEW_TARGET_LIMIT_FACTORY, - permissions=(create_permissions(contracts.simple_dvt, "updateTargetValidatorsLimits")), + permissions=( + create_permissions_overloaded( + contracts.simple_dvt, "updateTargetValidatorsLimits", "uint256,uint256,uint256" + ) + ), ), ) diff --git a/utils/easy_track.py b/utils/easy_track.py index ca04e9146..df3cc1eab 100644 --- a/utils/easy_track.py +++ b/utils/easy_track.py @@ -7,26 +7,18 @@ def add_evmscript_factory(factory: Contract | str, permissions: str) -> Tuple[str, str]: easy_track = contracts.easy_track - return ( - easy_track.address, - easy_track.addEVMScriptFactory.encode_input( - factory, - permissions - ) - ) + return (easy_track.address, easy_track.addEVMScriptFactory.encode_input(factory, permissions)) def remove_evmscript_factory(factory: Contract | str) -> Tuple[str, str]: easy_track = contracts.easy_track - return ( - easy_track.address, - easy_track.removeEVMScriptFactory.encode_input( - factory - ) - ) + return (easy_track.address, easy_track.removeEVMScriptFactory.encode_input(factory)) -def create_permissions_for_overloaded_method(contract: Contract, method: str, paramethers: Tuple[str, ...] = None) -> str: + +def create_permissions_for_overloaded_method( + contract: Contract, method: str, paramethers: Tuple[str, ...] = None +) -> str: method_description = getattr(contract, method) if len(method_description.methods) > 0: @@ -34,14 +26,16 @@ def create_permissions_for_overloaded_method(contract: Contract, method: str, pa return create_permissions(contract, method) + def create_permissions(contract: Contract, method: str) -> str: return contract.address + getattr(contract, method).signature[2:] +def create_permissions_overloaded(contract: Contract, method: str, func_args: str) -> str: + return contract.address + getattr(contract, method)[func_args].signature[2:] + + def set_motions_count_limit(motionsCountLimit: int) -> Tuple[str, str]: easy_track = contracts.easy_track - return ( - easy_track.address, - easy_track.setMotionsCountLimit.encode_input(motionsCountLimit) - ) + return (easy_track.address, easy_track.setMotionsCountLimit.encode_input(motionsCountLimit)) From 5886ab9c942c1c5fca856fe260b74ed112ae1fca Mon Sep 17 00:00:00 2001 From: maksim Date: Thu, 3 Oct 2024 10:50:09 +0200 Subject: [PATCH 117/220] test: fix post merge errors. --- .../regression/test_accounting_oracle_extra_data_full_items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 5b43cf092..8dad538db 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -56,7 +56,7 @@ def sdvt(interface): ) def test_extra_data_full_items( voting_eoa, evm_script_executor_eoa, nor, sdvt, extra_data_service, - nor_stuck_items, nor_exited_items, sdvt_stuck_items, sdvt_exited_items + nor_stuck_items, nor_exited_items, sdvt_stuck_items, sdvt_exited_items, stranger ): max_node_operators_per_item = MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM new_keys_per_operator = 2 From 999b674186122ae4d520cd45153789b666a1d22c Mon Sep 17 00:00:00 2001 From: VP Date: Wed, 7 Aug 2024 16:02:03 +0200 Subject: [PATCH 118/220] test: add basic negative rebase test --- .../test_neg_rebase_sanity_checks.py | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/regression/test_neg_rebase_sanity_checks.py diff --git a/tests/regression/test_neg_rebase_sanity_checks.py b/tests/regression/test_neg_rebase_sanity_checks.py new file mode 100644 index 000000000..66fea1fe8 --- /dev/null +++ b/tests/regression/test_neg_rebase_sanity_checks.py @@ -0,0 +1,39 @@ +import pytest +from brownie import Contract, web3, reverts, accounts, chain # type: ignore +from utils.test.exit_bus_data import LidoValidator +from utils.test.extra_data import ExtraDataService +from utils.test.oracle_report_helpers import ( + oracle_report, +) + +from utils.test.helpers import ETH +from utils.config import ( + contracts, +) + +@pytest.fixture(scope="module") +def oracle_report_sanity_checker() -> Contract: + return contracts.oracle_report_sanity_checker + + +def test_negative_rebase_correct_exited_validators_count(oracle_report_sanity_checker): + locator = contracts.lido_locator + assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() + + ids = contracts.staking_router.getStakingModuleIds() + exited = 0 + for id in ids: + exited += contracts.staking_router.getStakingModule(id)["exitedValidatorsCount"] + + reported_validators_count = exited + 2 + print(f'reported_validators_count: {reported_validators_count}') + + oracle_report(cl_diff=-ETH(40000), stakingModuleIdsWithNewlyExitedValidators=[1], + numExitedValidatorsByStakingModule=[reported_validators_count]) + + count = oracle_report_sanity_checker.getReportDataCount() + print(f'count: {count}') + assert count > 0 + (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) + + assert storedExitedValidators == reported_validators_count From f218f96f8b12871eb01de2a609b8882b1614325e Mon Sep 17 00:00:00 2001 From: VP Date: Thu, 8 Aug 2024 21:19:59 +0200 Subject: [PATCH 119/220] test: add more than 54 days of reports --- .../test_neg_rebase_sanity_checks.py | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/tests/regression/test_neg_rebase_sanity_checks.py b/tests/regression/test_neg_rebase_sanity_checks.py index 66fea1fe8..d50222df8 100644 --- a/tests/regression/test_neg_rebase_sanity_checks.py +++ b/tests/regression/test_neg_rebase_sanity_checks.py @@ -20,20 +20,41 @@ def test_negative_rebase_correct_exited_validators_count(oracle_report_sanity_ch locator = contracts.lido_locator assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() - ids = contracts.staking_router.getStakingModuleIds() - exited = 0 - for id in ids: - exited += contracts.staking_router.getStakingModule(id)["exitedValidatorsCount"] - - reported_validators_count = exited + 2 + reported_validators_count = exited_validators_count() + 2 print(f'reported_validators_count: {reported_validators_count}') oracle_report(cl_diff=-ETH(40000), stakingModuleIdsWithNewlyExitedValidators=[1], numExitedValidatorsByStakingModule=[reported_validators_count]) count = oracle_report_sanity_checker.getReportDataCount() - print(f'count: {count}') assert count > 0 (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) assert storedExitedValidators == reported_validators_count + +def test_negative_rebase_more_than_54_reports(oracle_report_sanity_checker): + locator = contracts.lido_locator + assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() + + reported_validators_count = exited_validators_count() + 2 + print(f'reported_validators_count: {reported_validators_count}') + + for _ in range(58): + reported_validators_count += 3 + oracle_report(cl_diff=-ETH(400), stakingModuleIdsWithNewlyExitedValidators=[1], + numExitedValidatorsByStakingModule=[reported_validators_count]) + + count = oracle_report_sanity_checker.getReportDataCount() + assert count > 0 + (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) + + assert storedExitedValidators == reported_validators_count + + +def exited_validators_count(): + ids = contracts.staking_router.getStakingModuleIds() + exited = 0 + for id in ids: + exited += contracts.staking_router.getStakingModule(id)["exitedValidatorsCount"] + + return exited From 98d0d995fc719ad2602506b0836a453ca8f0dde6 Mon Sep 17 00:00:00 2001 From: maksim Date: Thu, 3 Oct 2024 11:29:15 +0200 Subject: [PATCH 120/220] test: fix deploy parameters --- configs/config_mainnet.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 3d1abf789..ef31f3685 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -141,7 +141,7 @@ CURATED_STAKING_MODULE_OPERATORS_COUNT = 39 CURATED_STAKING_MODULE_OPERATORS_ACTIVE_COUNT = 37 CURATED_STAKING_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 10_000 -CURATED_STAKING_MODULE_MAX_DEPOSITS_PER_BLOCK = 50 +CURATED_STAKING_MODULE_MAX_DEPOSITS_PER_BLOCK = 150 CURATED_STAKING_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE = 25 # NodeOperatorsRegistry clone aka SimpleDVT @@ -161,8 +161,8 @@ "0x637572617465642d6f6e636861696e2d76310000000000000000000000000000" ) SIMPLE_DVT_VERSION = 3 -SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 10_000 -SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK = 50 +SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 400 +SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK = 150 SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE = 25 # OracleDaemonConfig From 71bf0f4629fb228c49bce42da5dd33bad54929b9 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Tue, 24 Sep 2024 13:40:01 +0500 Subject: [PATCH 121/220] fix for staking modules test --- tests/acceptance/test_staking_router.py | 60 ++++++++++++++++++------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/tests/acceptance/test_staking_router.py b/tests/acceptance/test_staking_router.py index 00adcd673..8b9aa58eb 100644 --- a/tests/acceptance/test_staking_router.py +++ b/tests/acceptance/test_staking_router.py @@ -1,6 +1,11 @@ import pytest from brownie import interface, reverts # type: ignore +from configs.config_mainnet import ( + CS_MODULE_ID, CS_MODULE_MODULE_FEE_BP, + CS_MODULE_TREASURY_FEE_BP, CS_MODULE_TARGET_SHARE_BP, CS_MODULE_NAME, CS_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_MODULE_MAX_DEPOSITS_PER_BLOCK, CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE, +) from utils.config import ( contracts, STAKING_ROUTER, @@ -95,22 +100,28 @@ def test_constants(contract): def test_staking_modules(contract): - assert contract.getStakingModulesCount() == 2 - - assert contract.getStakingModuleIds() == [CURATED_STAKING_MODULE_ID, SIMPLE_DVT_MODULE_ID] - assert contract.getStakingModuleIsActive(1) == True - assert contract.getStakingModuleIsStopped(1) == False - assert contract.getStakingModuleIsDepositsPaused(1) == False - assert contract.getStakingModuleNonce(1) >= 7260 - assert contract.getStakingModuleStatus(1) == 0 - - assert contract.getStakingModuleIsActive(2) == True - assert contract.getStakingModuleIsStopped(2) == False - assert contract.getStakingModuleIsDepositsPaused(2) == False - assert contract.getStakingModuleNonce(2) >= 0 - assert contract.getStakingModuleStatus(2) == 0 - - curated_module = contract.getStakingModule(1) + assert contract.getStakingModulesCount() == 3 + + assert contract.getStakingModuleIds() == [CURATED_STAKING_MODULE_ID, SIMPLE_DVT_MODULE_ID, CS_MODULE_ID] + assert contract.getStakingModuleIsActive(CURATED_STAKING_MODULE_ID) == True + assert contract.getStakingModuleIsStopped(CURATED_STAKING_MODULE_ID) == False + assert contract.getStakingModuleIsDepositsPaused(CURATED_STAKING_MODULE_ID) == False + assert contract.getStakingModuleNonce(CURATED_STAKING_MODULE_ID) >= 7260 + assert contract.getStakingModuleStatus(CURATED_STAKING_MODULE_ID) == 0 + + assert contract.getStakingModuleIsActive(SIMPLE_DVT_MODULE_ID) == True + assert contract.getStakingModuleIsStopped(SIMPLE_DVT_MODULE_ID) == False + assert contract.getStakingModuleIsDepositsPaused(SIMPLE_DVT_MODULE_ID) == False + assert contract.getStakingModuleNonce(SIMPLE_DVT_MODULE_ID) >= 0 + assert contract.getStakingModuleStatus(SIMPLE_DVT_MODULE_ID) == 0 + + assert contract.getStakingModuleIsActive(CS_MODULE_ID) == True + assert contract.getStakingModuleIsStopped(CS_MODULE_ID) == False + assert contract.getStakingModuleIsDepositsPaused(CS_MODULE_ID) == False + assert contract.getStakingModuleNonce(CS_MODULE_ID) >= 0 + assert contract.getStakingModuleStatus(CS_MODULE_ID) == 0 + + curated_module = contract.getStakingModule(CURATED_STAKING_MODULE_ID) assert curated_module["id"] == CURATED_STAKING_MODULE_ID assert curated_module["stakingModuleAddress"] == contracts.node_operators_registry assert curated_module["stakingModuleFee"] == CURATED_STAKING_MODULE_MODULE_FEE_BP @@ -125,7 +136,7 @@ def test_staking_modules(contract): assert curated_module["maxDepositsPerBlock"] == CURATED_STAKING_MODULE_MAX_DEPOSITS_PER_BLOCK assert curated_module["minDepositBlockDistance"] == CURATED_STAKING_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE - simple_dvt_module = contract.getStakingModule(2) + simple_dvt_module = contract.getStakingModule(SIMPLE_DVT_MODULE_ID) assert simple_dvt_module["id"] == SIMPLE_DVT_MODULE_ID assert simple_dvt_module["stakingModuleAddress"] == contracts.simple_dvt assert simple_dvt_module["stakingModuleFee"] == SIMPLE_DVT_MODULE_MODULE_FEE_BP @@ -140,6 +151,21 @@ def test_staking_modules(contract): assert simple_dvt_module["maxDepositsPerBlock"] == SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK assert curated_module["minDepositBlockDistance"] == SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE + community_staking_module = contract.getStakingModule(CS_MODULE_ID) + assert community_staking_module["id"] == CS_MODULE_ID + assert community_staking_module["stakingModuleAddress"] == contracts.csm + assert community_staking_module["stakingModuleFee"] == CS_MODULE_MODULE_FEE_BP + assert community_staking_module["treasuryFee"] == CS_MODULE_TREASURY_FEE_BP + assert community_staking_module["stakeShareLimit"] == CS_MODULE_TARGET_SHARE_BP + assert community_staking_module["status"] == 0 + assert community_staking_module["name"] == CS_MODULE_NAME + assert community_staking_module["lastDepositAt"] > 0 + assert community_staking_module["lastDepositBlock"] > 0 + assert community_staking_module["exitedValidatorsCount"] >= 0 + assert community_staking_module["priorityExitShareThreshold"] == CS_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD + assert community_staking_module["maxDepositsPerBlock"] == CS_MODULE_MAX_DEPOSITS_PER_BLOCK + assert curated_module["minDepositBlockDistance"] == CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE + fee_aggregate_distribution = contract.getStakingFeeAggregateDistribution() assert fee_aggregate_distribution["modulesFee"] <= SR_MODULES_FEE_E20 assert fee_aggregate_distribution["treasuryFee"] >= SR_TREASURY_FEE_E20 From 11e699d6bb9ef5023b9167dd898b52c210e25122 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Wed, 25 Sep 2024 12:13:21 +0500 Subject: [PATCH 122/220] add claim rewards tests --- interfaces/csm/CSFeeOracle.json | 2776 +++++++++++++-------------- tests/regression/test_csm.py | 83 +- utils/test/merkle_tree.py | 199 ++ utils/test/oracle_report_helpers.py | 46 +- 4 files changed, 1694 insertions(+), 1410 deletions(-) create mode 100644 utils/test/merkle_tree.py diff --git a/interfaces/csm/CSFeeOracle.json b/interfaces/csm/CSFeeOracle.json index 1b56f6a41..d08f0a893 100644 --- a/interfaces/csm/CSFeeOracle.json +++ b/interfaces/csm/CSFeeOracle.json @@ -1,1397 +1,1381 @@ [ - { - "type": "constructor", - "inputs": [ - { - "name": "secondsPerSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "genesisTime", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "CONTRACT_MANAGER_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "DEFAULT_ADMIN_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "GENESIS_TIME", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "MANAGE_CONSENSUS_CONTRACT_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "MANAGE_CONSENSUS_VERSION_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "PAUSE_INFINITELY", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "PAUSE_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "RECOVERER_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "RESUME_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "SECONDS_PER_SLOT", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "SUBMIT_DATA_ROLE", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "avgPerfLeewayBP", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "discardConsensusReport", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "feeDistributor", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "contract ICSFeeDistributor" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getConsensusContract", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getConsensusReport", - "inputs": [], - "outputs": [ - { - "name": "hash", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "processingDeadlineTime", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "processingStarted", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getConsensusVersion", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getContractVersion", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getLastProcessingRefSlot", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getResumeSinceTimestamp", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleAdmin", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleMember", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "index", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "getRoleMemberCount", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - } - ], - "outputs": [ - { - "name": "", - "type": "uint256", - "internalType": "uint256" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "grantRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "hasRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "initialize", - "inputs": [ - { - "name": "admin", - "type": "address", - "internalType": "address" - }, - { - "name": "feeDistributorContract", - "type": "address", - "internalType": "address" - }, - { - "name": "consensusContract", - "type": "address", - "internalType": "address" - }, - { - "name": "consensusVersion", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "_avgPerfLeewayBP", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "isPaused", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "function", - "name": "pauseFor", - "inputs": [ - { - "name": "duration", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "pauseUntil", - "inputs": [ - { - "name": "pauseUntilInclusive", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC1155", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC20", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverERC721", - "inputs": [ - { - "name": "token", - "type": "address", - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "recoverEther", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "renounceRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "callerConfirmation", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "resume", - "inputs": [], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "revokeRole", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setConsensusContract", - "inputs": [ - { - "name": "addr", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setConsensusVersion", - "inputs": [ - { - "name": "version", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setFeeDistributorContract", - "inputs": [ - { - "name": "feeDistributorContract", - "type": "address", - "internalType": "address" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "setPerformanceLeeway", - "inputs": [ - { - "name": "valueBP", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "submitConsensusReport", - "inputs": [ - { - "name": "reportHash", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "deadline", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "submitReportData", - "inputs": [ - { - "name": "data", - "type": "tuple", - "internalType": "struct CSFeeOracle.ReportData", - "components": [ - { - "name": "consensusVersion", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "treeRoot", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "treeCid", - "type": "string", - "internalType": "string" - }, - { - "name": "distributed", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "name": "contractVersion", - "type": "uint256", - "internalType": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - }, - { - "type": "function", - "name": "supportsInterface", - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4", - "internalType": "bytes4" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, - { - "type": "event", - "name": "ConsensusHashContractSet", - "inputs": [ - { - "name": "addr", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "prevAddr", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ConsensusVersionSet", - "inputs": [ - { - "name": "version", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "prevVersion", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ContractVersionSet", - "inputs": [ - { - "name": "version", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ERC1155Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ERC20Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ERC721Recovered", - "inputs": [ - { - "name": "token", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "tokenId", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "EtherRecovered", - "inputs": [ - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "FeeDistributorContractSet", - "inputs": [ - { - "name": "feeDistributorContract", - "type": "address", - "indexed": false, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Initialized", - "inputs": [ - { - "name": "version", - "type": "uint64", - "indexed": false, - "internalType": "uint64" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Paused", - "inputs": [ - { - "name": "duration", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "PerfLeewaySet", - "inputs": [ - { - "name": "valueBP", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ProcessingStarted", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "hash", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ReportDiscarded", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "hash", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ReportSettled", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "distributed", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - }, - { - "name": "treeRoot", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - }, - { - "name": "treeCid", - "type": "string", - "indexed": false, - "internalType": "string" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "ReportSubmitted", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - }, - { - "name": "hash", - "type": "bytes32", - "indexed": false, - "internalType": "bytes32" - }, - { - "name": "processingDeadlineTime", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "Resumed", - "inputs": [], - "anonymous": false - }, - { - "type": "event", - "name": "RoleAdminChanged", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "previousAdminRole", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "newAdminRole", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleGranted", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "RoleRevoked", - "inputs": [ - { - "name": "role", - "type": "bytes32", - "indexed": true, - "internalType": "bytes32" - }, - { - "name": "account", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "sender", - "type": "address", - "indexed": true, - "internalType": "address" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "StETHSharesRecovered", - "inputs": [ - { - "name": "recipient", - "type": "address", - "indexed": true, - "internalType": "address" - }, - { - "name": "shares", - "type": "uint256", - "indexed": false, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "event", - "name": "WarnProcessingMissed", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "indexed": true, - "internalType": "uint256" - } - ], - "anonymous": false - }, - { - "type": "error", - "name": "AccessControlBadConfirmation", - "inputs": [] - }, - { - "type": "error", - "name": "AccessControlUnauthorizedAccount", - "inputs": [ - { - "name": "account", - "type": "address", - "internalType": "address" - }, - { - "name": "neededRole", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "type": "error", - "name": "AddressCannotBeSame", - "inputs": [] - }, - { - "type": "error", - "name": "AddressCannotBeZero", - "inputs": [] - }, - { - "type": "error", - "name": "FailedToSendEther", - "inputs": [] - }, - { - "type": "error", - "name": "HashCannotBeZero", - "inputs": [] - }, - { - "type": "error", - "name": "InitialRefSlotCannotBeLessThanProcessingOne", - "inputs": [ - { - "name": "initialRefSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "processingRefSlot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "InvalidContractVersionIncrement", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidInitialization", - "inputs": [] - }, - { - "type": "error", - "name": "InvalidPerfLeeway", - "inputs": [] - }, - { - "type": "error", - "name": "NoConsensusReportToProcess", - "inputs": [] - }, - { - "type": "error", - "name": "NonZeroContractVersionOnInit", - "inputs": [] - }, - { - "type": "error", - "name": "NotAllowedToRecover", - "inputs": [] - }, - { - "type": "error", - "name": "NotInitializing", - "inputs": [] - }, - { - "type": "error", - "name": "PauseUntilMustBeInFuture", - "inputs": [] - }, - { - "type": "error", - "name": "PausedExpected", - "inputs": [] - }, - { - "type": "error", - "name": "ProcessingDeadlineMissed", - "inputs": [ - { - "name": "deadline", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "RefSlotAlreadyProcessing", - "inputs": [] - }, - { - "type": "error", - "name": "RefSlotCannotDecrease", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "prevRefSlot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "RefSlotMustBeGreaterThanProcessingOne", - "inputs": [ - { - "name": "refSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "processingRefSlot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "ResumedExpected", - "inputs": [] - }, - { - "type": "error", - "name": "SafeCastOverflowedUintDowncast", - "inputs": [ - { - "name": "bits", - "type": "uint8", - "internalType": "uint8" - }, - { - "name": "value", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "SecondsPerSlotCannotBeZero", - "inputs": [] - }, - { - "type": "error", - "name": "SenderIsNotTheConsensusContract", - "inputs": [] - }, - { - "type": "error", - "name": "SenderNotAllowed", - "inputs": [] - }, - { - "type": "error", - "name": "UnexpectedChainConfig", - "inputs": [] - }, - { - "type": "error", - "name": "UnexpectedConsensusVersion", - "inputs": [ - { - "name": "expectedVersion", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "receivedVersion", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "UnexpectedContractVersion", - "inputs": [ - { - "name": "expected", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "received", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "UnexpectedDataHash", - "inputs": [ - { - "name": "consensusHash", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "receivedHash", - "type": "bytes32", - "internalType": "bytes32" - } - ] - }, - { - "type": "error", - "name": "UnexpectedRefSlot", - "inputs": [ - { - "name": "consensusRefSlot", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "dataRefSlot", - "type": "uint256", - "internalType": "uint256" - } - ] - }, - { - "type": "error", - "name": "VersionCannotBeSame", - "inputs": [] - }, - { - "type": "error", - "name": "ZeroAdminAddress", - "inputs": [] - }, - { - "type": "error", - "name": "ZeroFeeDistributorAddress", - "inputs": [] - }, - { - "type": "error", - "name": "ZeroPauseDuration", - "inputs": [] - } - ] + { + "inputs": [ + { + "internalType": "uint256", + "name": "secondsPerSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "genesisTime", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccessControlBadConfirmation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "neededRole", + "type": "bytes32" + } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "AddressCannotBeSame", + "type": "error" + }, + { + "inputs": [], + "name": "AddressCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "FailedToSendEther", + "type": "error" + }, + { + "inputs": [], + "name": "HashCannotBeZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "initialRefSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingRefSlot", + "type": "uint256" + } + ], + "name": "InitialRefSlotCannotBeLessThanProcessingOne", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidContractVersion", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidContractVersionIncrement", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPerfLeeway", + "type": "error" + }, + { + "inputs": [], + "name": "NoConsensusReportToProcess", + "type": "error" + }, + { + "inputs": [], + "name": "NonZeroContractVersionOnInit", + "type": "error" + }, + { + "inputs": [], + "name": "NotAllowedToRecover", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "PauseUntilMustBeInFuture", + "type": "error" + }, + { + "inputs": [], + "name": "PausedExpected", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "ProcessingDeadlineMissed", + "type": "error" + }, + { + "inputs": [], + "name": "RefSlotAlreadyProcessing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "prevRefSlot", + "type": "uint256" + } + ], + "name": "RefSlotCannotDecrease", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingRefSlot", + "type": "uint256" + } + ], + "name": "RefSlotMustBeGreaterThanProcessingOne", + "type": "error" + }, + { + "inputs": [], + "name": "ResumedExpected", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "bits", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { + "inputs": [], + "name": "SecondsPerSlotCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "SenderIsNotTheConsensusContract", + "type": "error" + }, + { + "inputs": [], + "name": "SenderNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "UnexpectedChainConfig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedVersion", + "type": "uint256" + } + ], + "name": "UnexpectedConsensusVersion", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "UnexpectedContractVersion", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "consensusHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "receivedHash", + "type": "bytes32" + } + ], + "name": "UnexpectedDataHash", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "consensusRefSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dataRefSlot", + "type": "uint256" + } + ], + "name": "UnexpectedRefSlot", + "type": "error" + }, + { + "inputs": [], + "name": "VersionCannotBeSame", + "type": "error" + }, + { + "inputs": [], + "name": "VersionCannotBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAdminAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroFeeDistributorAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroPauseDuration", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "prevAddr", + "type": "address" + } + ], + "name": "ConsensusHashContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "prevVersion", + "type": "uint256" + } + ], + "name": "ConsensusVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + } + ], + "name": "ContractVersionSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ERC1155Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ERC20Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "ERC721Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EtherRecovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeDistributorContract", + "type": "address" + } + ], + "name": "FeeDistributorContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "duration", + "type": "uint256" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "valueBP", + "type": "uint256" + } + ], + "name": "PerfLeewaySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "ProcessingStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "name": "ReportDiscarded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "processingDeadlineTime", + "type": "uint256" + } + ], + "name": "ReportSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Resumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "StETHSharesRecovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + } + ], + "name": "WarnProcessingMissed", + "type": "event" + }, + { + "inputs": [], + "name": "CONTRACT_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GENESIS_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_CONSENSUS_CONTRACT_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGE_CONSENSUS_VERSION_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSE_INFINITELY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSE_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RECOVERER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESUME_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SECONDS_PER_SLOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUBMIT_DATA_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "avgPerfLeewayBP", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + } + ], + "name": "discardConsensusReport", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeDistributor", + "outputs": [ + { + "internalType": "contract ICSFeeDistributor", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusReport", + "outputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "processingDeadlineTime", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "processingStarted", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getConsensusVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getContractVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastProcessingRefSlot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getResumeSinceTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "feeDistributorContract", + "type": "address" + }, + { + "internalType": "address", + "name": "consensusContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_avgPerfLeewayBP", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + } + ], + "name": "pauseFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pauseUntilInclusive", + "type": "uint256" + } + ], + "name": "pauseUntil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "recoverERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "recoverERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "recoverEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resume", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "setConsensusContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "version", + "type": "uint256" + } + ], + "name": "setConsensusVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeDistributorContract", + "type": "address" + } + ], + "name": "setFeeDistributorContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "valueBP", + "type": "uint256" + } + ], + "name": "setPerformanceLeeway", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "reportHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "submitConsensusReport", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "consensusVersion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refSlot", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "treeRoot", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "treeCid", + "type": "string" + }, + { + "internalType": "string", + "name": "logCid", + "type": "string" + }, + { + "internalType": "uint256", + "name": "distributed", + "type": "uint256" + } + ], + "internalType": "struct CSFeeOracle.ReportData", + "name": "data", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "contractVersion", + "type": "uint256" + } + ], + "name": "submitReportData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py index 7b7dfd7a6..abcf62d30 100644 --- a/tests/regression/test_csm.py +++ b/tests/regression/test_csm.py @@ -11,7 +11,10 @@ from utils.test.csm_helpers import csm_add_node_operator, get_ea_member, csm_upload_keys from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.helpers import ETH -from utils.test.oracle_report_helpers import oracle_report +from utils.test.oracle_report_helpers import ( + oracle_report, wait_to_next_available_report_time, prepare_csm_report, + reach_consensus, +) from utils.test.staking_router_helpers import set_staking_module_status, StakingModuleStatus contracts: ContractsLazyLoader = contracts @@ -34,29 +37,64 @@ def fee_distributor(): return contracts.cs_fee_distributor -@pytest.fixture() +@pytest.fixture(scope="module") +def fee_oracle(): + return contracts.cs_fee_oracle + + +@pytest.fixture def node_operator(csm, accounting) -> int: address, proof = get_ea_member() return csm_add_node_operator(csm, accounting, address, proof) -@pytest.fixture() +@pytest.fixture def pause_modules(): # pause deposit to all modules except csm - # to be sure that all deposits go to csm + # to be sure that all deposits goes to csm modules = contracts.staking_router.getStakingModules() for module in modules: if module[0] != CSM_MODULE_ID: set_staking_module_status(module[0], StakingModuleStatus.Stopped) -@pytest.fixture() +@pytest.fixture def deposits_to_csm(csm, pause_modules, node_operator): (_, _, depositable) = csm.getStakingModuleSummary() fill_deposit_buffer(depositable) contracts.lido.deposit(depositable, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module}) +@pytest.fixture +def ref_slot(): + wait_to_next_available_report_time(contracts.csm_hash_consensus) + ref_slot, _ = contracts.csm_hash_consensus.getCurrentFrame() + return ref_slot + + +@pytest.fixture +def distribute_reward_tree(deposits_to_csm, fee_oracle, fee_distributor, node_operator, ref_slot): + consensus_version = fee_oracle.getConsensusVersion() + oracle_version = fee_oracle.getContractVersion() + + rewards = ETH(0.05) + oracle_report(cl_diff=rewards) + distributed_shares = contracts.lido.sharesOf(fee_distributor) + assert distributed_shares > 0 + + report, report_hash, tree = prepare_csm_report({node_operator: distributed_shares}, ref_slot) + + submitter = reach_consensus( + ref_slot, + report_hash, + consensus_version, + contracts.csm_hash_consensus, + ) + + fee_oracle.submitReportData(report, oracle_version, {"from": submitter}) + return tree + + @pytest.mark.usefixtures("pause_modules") def test_deposit(node_operator, csm): (_, _, depositable_validators_count) = csm.getStakingModuleSummary() @@ -218,3 +256,38 @@ def test_csm_decrease_vetted_keys(csm, node_operator, stranger): no = csm.getNodeOperator(node_operator) assert no["totalVettedKeys"] == 1 + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_claim_rewards_steth(csm, distribute_reward_tree, node_operator, fee_distributor): + tree = distribute_reward_tree.tree + shares = tree.values[0]["value"][1] + proof = list(tree.get_proof(tree.find(tree.leaf((node_operator, shares))))) + reward_address = csm.getNodeOperator(node_operator)["rewardAddress"] + shares_before = contracts.lido.sharesOf(reward_address) + + csm.claimRewardsStETH(node_operator, ETH(1), shares, proof, {"from": reward_address}) + # subtract 10 to avoid rounding errors + assert contracts.lido.sharesOf(reward_address) > shares_before + shares - 10 + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_claim_rewards_wsteth(csm, distribute_reward_tree, node_operator, fee_distributor): + tree = distribute_reward_tree.tree + shares = tree.values[0]["value"][1] + proof = list(tree.get_proof(tree.find(tree.leaf((node_operator, shares))))) + reward_address = csm.getNodeOperator(node_operator)["rewardAddress"] + wsteth_before = contracts.wsteth.balanceOf(reward_address) + + csm.claimRewardsWstETH(node_operator, ETH(1), shares, proof, {"from": reward_address}) + assert contracts.wsteth.balanceOf(reward_address) > wsteth_before + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_claim_rewards_eth(csm, distribute_reward_tree, node_operator, fee_distributor): + tree = distribute_reward_tree.tree + shares = tree.values[0]["value"][1] + proof = list(tree.get_proof(tree.find(tree.leaf((node_operator, shares))))) + reward_address = csm.getNodeOperator(node_operator)["rewardAddress"] + withdrawal_requests = contracts.withdrawal_queue.getWithdrawalRequests(reward_address) + + csm.claimRewardsUnstETH(node_operator, ETH(1), shares, proof, {"from": reward_address}) + + assert len(contracts.withdrawal_queue.getWithdrawalRequests(reward_address)) == len(withdrawal_requests) + 1 diff --git a/utils/test/merkle_tree.py b/utils/test/merkle_tree.py new file mode 100644 index 000000000..7abfe65a0 --- /dev/null +++ b/utils/test/merkle_tree.py @@ -0,0 +1,199 @@ +# copied from lido-oracle +import json +from abc import abstractmethod, ABC +from dataclasses import dataclass +from functools import reduce +from typing import Collection, Generic, Iterable, Sequence, TypedDict, TypeVar, TypeAlias + +from hexbytes import HexBytes +from eth_abi.abi import encode +from eth_hash.auto import keccak +from eth_typing import TypeStr + +Shares: TypeAlias = int +NodeOperatorId: TypeAlias = int +RewardTreeLeaf: TypeAlias = tuple[NodeOperatorId, Shares] + + +class TreeJSONEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, bytes): + return f"0x{o.hex()}" + return super().default(o) + +class MerkleTree(ABC): + """Merkle Tree interface""" + + @property + @abstractmethod + def root(self) -> bytes: ... + + @abstractmethod + def find(self, leaf: bytes) -> int: ... + + @abstractmethod + def get_proof(self, index: int) -> Iterable[bytes]: ... + + @classmethod + @abstractmethod + def verify(cls, root: bytes, leaf: bytes, proof: Iterable[bytes]) -> bool: ... + + @classmethod + @abstractmethod + def __hash_leaf__(cls, leaf: bytes) -> bytes: ... + + @classmethod + @abstractmethod + def __hash_node__(cls, lhs: bytes, rhs: bytes) -> bytes: ... + + +class CompleteBinaryMerkleTree(MerkleTree): + """The tree shaped as a [complete binary tree](https://xlinux.nist.gov/dads/HTML/completeBinaryTree.html).""" + + tree: tuple[bytes, ...] + + def __init__(self, leaves: Collection[bytes]): + if not leaves: + raise ValueError("Attempt to create an empty tree") + + tree = [b""] * (2 * len(leaves) - 1) + + for i, leaf in enumerate(leaves): + tree[len(tree) - 1 - i] = leaf + + for i in range(len(tree) - 1 - len(leaves), -1, -1): + tree[i] = self.__hash_node__(tree[2 * i + 1], tree[2 * i + 2]) + + self.tree = tuple(tree) + + @property + def root(self) -> bytes: + return self.tree[0] + + def find(self, leaf: bytes) -> int: + try: + return self.tree.index(leaf) + except ValueError as e: + raise ValueError("Node not found") from e + + def get_proof(self, index: int) -> Iterable[bytes]: + i = index + while i > 0: + yield self.tree[i - (-1) ** (i % 2)] + i = (i - 1) // 2 + + @classmethod + def verify(cls, root: bytes, leaf: bytes, proof: Iterable[bytes]) -> bool: + return reduce(lambda a, b: cls.__hash_node__(a, b), proof, leaf) == root + + +T = TypeVar("T", bound=Iterable) + + +class Value(TypedDict): + value: T + treeIndex: int + + +class Dump(TypedDict): + format: str + leafEncoding: Iterable[TypeStr] + tree: Collection[bytes] + values: Sequence[Value[T]] + + +class StandardMerkleTree(Generic[T], CompleteBinaryMerkleTree): + """ + OpenZeppelin Standard Merkle Tree + + - The tree is shaped as a complete binary tree. + - The leaves are sorted. + - The leaves are the result of ABI encoding a series of values. + - The hash used is Keccak256. + - The leaves are double-hashed to prevent second preimage attacks. + """ + + encoding: Iterable[TypeStr] + values: Sequence[Value[T]] + + FORMAT = "standard-v1" + + def __init__(self, values: Sequence[T], encoding: Iterable[TypeStr]): + self.encoding = encoding + + leaves = tuple(sorted(self.leaf(v) for v in values)) + super().__init__(leaves) + + self.values = tuple({"value": v, "treeIndex": self.find(self.leaf(v))} for v in values) + + def leaf(self, value: T) -> bytes: + return self.__hash_leaf__(encode(self.encoding, value)) + + def dump(self) -> Dump[T]: + return { + "format": self.FORMAT, + "leafEncoding": self.encoding, + "tree": self.tree, + "values": self.values, + } + + @classmethod + def load(cls, data: Dump[T]): + if "format" not in data or data["format"] != cls.FORMAT: + raise ValueError("Unexpected dump format value") + if "leafEncoding" not in data: + raise ValueError("No leaf encoding provided") + if "values" not in data: + raise ValueError("No values provided") + return cls([e["value"] for e in data["values"]], data["leafEncoding"]) + + @classmethod + def __hash_leaf__(cls, leaf: bytes) -> bytes: + return keccak(keccak(leaf)) + + @classmethod + def __hash_node__(cls, lhs: bytes, rhs: bytes) -> bytes: + if lhs > rhs: + lhs, rhs = rhs, lhs + return keccak(lhs + rhs) + + +@dataclass +class Tree: + """A wrapper around StandardMerkleTree to cover use cases of the CSM oracle""" + + tree: StandardMerkleTree[tuple[int, int]] + + @property + def root(self) -> HexBytes: + return HexBytes(self.tree.root) + + @classmethod + def decode(cls, content: bytes): + """Restore a tree from a supported binary representation""" + + try: + return cls(StandardMerkleTree.load(json.loads(content))) + except json.JSONDecodeError as e: + raise ValueError("Unsupported tree format") from e + + def encode(self) -> bytes: + """Convert the underlying StandardMerkleTree to a binary representation""" + + return ( + TreeJSONEncoder( + indent=None, + separators=(',', ':'), + sort_keys=True, + ) + .encode(self.dump()) + .encode() + ) + + def dump(self) -> Dump[RewardTreeLeaf]: + return self.tree.dump() + + @classmethod + def new(cls, values: Sequence[RewardTreeLeaf]): + """Create new instance around the wrapped tree out of the given values""" + return cls(StandardMerkleTree(values, ("uint256", "uint256"))) diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index 41edd0ed6..2433b0be7 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -11,14 +11,16 @@ from utils.config import (contracts, AO_CONSENSUS_VERSION) from utils.test.exit_bus_data import encode_data from utils.test.helpers import ETH, GWEI, eth_balance +from utils.test.merkle_tree import Tree ZERO_HASH = bytes([0] * 32) ZERO_BYTES32 = HexBytes(ZERO_HASH) ONE_DAY = 1 * 24 * 60 * 60 -SHARE_RATE_PRECISION = 10**27 +SHARE_RATE_PRECISION = 10 ** 27 EXTRA_DATA_FORMAT_EMPTY = 0 EXTRA_DATA_FORMAT_LIST = 1 + @dataclass class AccountingReport: """Accounting oracle ReportData struct""" @@ -57,7 +59,6 @@ def copy(self) -> "AccountingReport": return AccountingReport(*self.items) - def prepare_accounting_report( *, refSlot, @@ -107,6 +108,31 @@ def prepare_exit_bus_report(validators_to_exit, ref_slot): return report, report_hash +def prepare_csm_report(node_operators_rewards: dict, ref_slot): + consensus_version = contracts.cs_fee_oracle.getConsensusVersion() + shares = node_operators_rewards.copy() + if len(shares) < 2: + # put a stone + shares[2 ** 64 - 1] = 0 + + tree = Tree.new(tuple((no_id, amount) for (no_id, amount) in shares.items())) + # semi-random values + log_cid = web3.keccak(tree.root) + tree_cid = web3.keccak(log_cid) + + report = ( + consensus_version, + ref_slot, + tree.root, + str(tree_cid), + str(log_cid), + sum(shares.values()), + ) + report_data = encode_data_from_abi(report, contracts.cs_fee_oracle.abi, "submitReportData") + report_hash = web3.keccak(report_data) + return report, report_hash, tree + + def encode_data_from_abi(data, abi, func_name): report_function_abi = next(x for x in abi if x.get("name") == func_name) report_data_abi = report_function_abi["inputs"][0]["components"] # type: ignore @@ -117,7 +143,8 @@ def encode_data_from_abi(data, abi, func_name): def get_finalization_batches( share_rate: int, limited_withdrawal_vault_balance, limited_el_rewards_vault_balance ) -> list[int]: - (_, _, _, _, _, _, _, requestTimestampMargin, _, _, _, _) = contracts.oracle_report_sanity_checker.getOracleReportLimits() + (_, _, _, _, _, _, _, requestTimestampMargin, _, _, _, + _) = contracts.oracle_report_sanity_checker.getOracleReportLimits() buffered_ether = contracts.lido.getBufferedEther() unfinalized_steth = contracts.withdrawal_queue.unfinalizedStETH() reserved_buffer = min(buffered_ether, unfinalized_steth) @@ -168,7 +195,7 @@ def push_oracle_report( extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, silent=False, - extraDataList:List[bytes]=[], + extraDataList: List[bytes] = [], ): if not silent: print(f"Preparing oracle report for refSlot: {refSlot}") @@ -192,7 +219,7 @@ def push_oracle_report( extraDataItemsCount=extraDataItemsCount, ) submitter = reach_consensus(refSlot, hash, consensusVersion, contracts.hash_consensus_for_accounting_oracle, silent) - accounts[0].transfer(submitter, 10**19) + accounts[0].transfer(submitter, 10 ** 19) # print(contracts.oracle_report_sanity_checker.getOracleReportLimits()) report_tx = contracts.accounting_oracle.submitReportData(items, oracleVersion, {"from": submitter}) if not silent: @@ -203,7 +230,8 @@ def push_oracle_report( if not silent: print("Submitted empty extra data report") else: - extra_report_tx_list = [contracts.accounting_oracle.submitReportExtraDataList(data, {"from": submitter}) for data in extraDataList] + extra_report_tx_list = [contracts.accounting_oracle.submitReportExtraDataList(data, {"from": submitter}) for + data in extraDataList] if not silent: print("Submitted NOT empty extra data report") @@ -294,7 +322,7 @@ def oracle_report( extraDataFormat=0, extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, - extraDataList:List[bytes]=[], + extraDataList: List[bytes] = [], stakingModuleIdsWithNewlyExitedValidators=[], numExitedValidatorsByStakingModule=[], silent=False, @@ -322,7 +350,7 @@ def oracle_report( extraDataFormat=0, extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, - extraDataList:List[bytes]=[], + extraDataList: List[bytes] = [], stakingModuleIdsWithNewlyExitedValidators=[], numExitedValidatorsByStakingModule=[], silent=False, @@ -350,7 +378,7 @@ def oracle_report( extraDataFormat=0, extraDataHashList=[ZERO_BYTES32], extraDataItemsCount=0, - extraDataList:List[bytes]=[], + extraDataList: List[bytes] = [], stakingModuleIdsWithNewlyExitedValidators=[], numExitedValidatorsByStakingModule=[], silent=False, From c8353eefbc96d72c263f9ee131976783be16a718 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Wed, 25 Sep 2024 12:36:07 +0500 Subject: [PATCH 123/220] fixes for review comments --- tests/acceptance/test_staking_router.py | 4 ++-- tests/regression/test_csm.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/acceptance/test_staking_router.py b/tests/acceptance/test_staking_router.py index 8b9aa58eb..f4f091816 100644 --- a/tests/acceptance/test_staking_router.py +++ b/tests/acceptance/test_staking_router.py @@ -149,7 +149,7 @@ def test_staking_modules(contract): assert simple_dvt_module["exitedValidatorsCount"] >= 0 assert simple_dvt_module["priorityExitShareThreshold"] == SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD assert simple_dvt_module["maxDepositsPerBlock"] == SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK - assert curated_module["minDepositBlockDistance"] == SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE + assert simple_dvt_module["minDepositBlockDistance"] == SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE community_staking_module = contract.getStakingModule(CS_MODULE_ID) assert community_staking_module["id"] == CS_MODULE_ID @@ -164,7 +164,7 @@ def test_staking_modules(contract): assert community_staking_module["exitedValidatorsCount"] >= 0 assert community_staking_module["priorityExitShareThreshold"] == CS_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD assert community_staking_module["maxDepositsPerBlock"] == CS_MODULE_MAX_DEPOSITS_PER_BLOCK - assert curated_module["minDepositBlockDistance"] == CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE + assert community_staking_module["minDepositBlockDistance"] == CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE fee_aggregate_distribution = contract.getStakingFeeAggregateDistribution() assert fee_aggregate_distribution["modulesFee"] <= SR_MODULES_FEE_E20 diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py index abcf62d30..f08141d83 100644 --- a/tests/regression/test_csm.py +++ b/tests/regression/test_csm.py @@ -213,6 +213,7 @@ def test_csm_get_staking_module_summary(csm, accounting, node_operator, extra_da @pytest.mark.usefixtures("deposits_to_csm") def test_csm_get_node_operator_summary(csm, node_operator, extra_data_service): + no = csm.getNodeOperator(node_operator) exited_keys = 1 stuck_keys = 1 extra_data = extra_data_service.collect({(CSM_MODULE_ID, node_operator): stuck_keys}, {(CSM_MODULE_ID, node_operator): exited_keys}, 2, 2) @@ -232,7 +233,7 @@ def test_csm_get_node_operator_summary(csm, node_operator, extra_data_service): assert summary["refundedValidatorsCount"] == 0 assert summary["stuckPenaltyEndTimestamp"] == 0 assert summary["totalExitedValidators"] == exited_keys - assert summary["totalDepositedValidators"] == 5 + assert summary["totalDepositedValidators"] == no["totalDepositedKeys"] assert summary["depositableValidatorsCount"] == 0 From f021db50bf4da05e5b0d5dbae792f21561c6f84e Mon Sep 17 00:00:00 2001 From: skhomuti Date: Thu, 26 Sep 2024 13:27:58 +0500 Subject: [PATCH 124/220] fixed extra data full list test added csm support optimized for better execution time --- tests/acceptance/test_csm.py | 2 +- tests/conftest.py | 2 +- tests/regression/conftest.py | 11 +- ...accounting_oracle_extra_data_full_items.py | 197 +++++++++++------- tests/regression/test_csm.py | 4 +- .../test_staking_router_stake_distribution.py | 2 +- utils/node_operators.py | 1 - utils/test/csm_helpers.py | 19 +- 8 files changed, 152 insertions(+), 86 deletions(-) diff --git a/tests/acceptance/test_csm.py b/tests/acceptance/test_csm.py index 7d8a4b107..3ae8699d4 100644 --- a/tests/acceptance/test_csm.py +++ b/tests/acceptance/test_csm.py @@ -173,7 +173,7 @@ def test_initial_state(self, hash_consensus): # TODO uncomment this when initial ref slot is known # assert frame_config["initialEpoch"] > 5254400 / CHAIN_SLOTS_PER_EPOCH assert frame_config["epochsPerFrame"] == CS_ORACLE_EPOCHS_PER_FRAME - assert frame_config["fastLaneLengthSlots"] == 0 + assert frame_config["fastLaneLengthSlots"] == 1800 assert hash_consensus.getQuorum() == ORACLE_QUORUM diff --git a/tests/conftest.py b/tests/conftest.py index 9bb9d5f17..137118b6b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -47,7 +47,7 @@ def ldo_holder(accounts): return accounts.at(LDO_HOLDER_ADDRESS_FOR_TESTS, force=True) -@pytest.fixture(scope="function") +@pytest.fixture(scope="session") def stranger(): return set_balance("0x98eC059dC3aDFbdd63429454aeB0C990fbA4a124", 100000) diff --git a/tests/regression/conftest.py b/tests/regression/conftest.py index 099afb95a..2dae114e9 100644 --- a/tests/regression/conftest.py +++ b/tests/regression/conftest.py @@ -14,7 +14,16 @@ @pytest.fixture(scope="function", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) -def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger): +def autoexecute_vote(request, helpers, vote_ids_from_env, accounts, stranger): + if "autoexecute_vote_ms" in request.node.fixturenames: + return + autoexecute_vote_impl(helpers, vote_ids_from_env, accounts, stranger) + +@pytest.fixture(scope="module") +def autoexecute_vote_ms(helpers, vote_ids_from_env, accounts, stranger): + autoexecute_vote_impl(helpers, vote_ids_from_env, accounts, stranger) + +def autoexecute_vote_impl(helpers, vote_ids_from_env, accounts, stranger): if vote_ids_from_env: helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") else: diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 8dad538db..dcdfe671a 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -3,6 +3,7 @@ from brownie.network.account import Account from brownie.network.web3 import Web3 +from utils.test.csm_helpers import csm_add_node_operator, csm_upload_keys from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.helpers import shares_balance, almostEqWithDiff from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch @@ -11,95 +12,113 @@ from utils.config import MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM from utils.config import contracts -from utils.test.simple_dvt_helpers import simple_dvt_add_node_operators, simple_dvt_add_keys, simple_dvt_vet_keys +NEW_KEYS_PER_OPERATOR = 2 -@pytest.fixture +pytestmark = pytest.mark.usefixtures("autoexecute_vote_ms") + +@pytest.fixture(scope="module") def voting_eoa(accounts): return accounts.at(contracts.voting.address, force=True) -@pytest.fixture +@pytest.fixture(scope="module") +def agent_eoa(accounts): + return accounts.at(contracts.agent.address, force=True) + + +@pytest.fixture(scope="module") def evm_script_executor_eoa(accounts): return accounts.at(contracts.easy_track.evmScriptExecutor(), force=True) -@pytest.fixture +@pytest.fixture(scope="module") def nor(interface): return interface.NodeOperatorsRegistry(contracts.node_operators_registry.address) -@pytest.fixture +@pytest.fixture(scope="module") def sdvt(interface): return interface.SimpleDVT(contracts.simple_dvt.address) -@pytest.mark.parametrize( - ("nor_stuck_items", "nor_exited_items", "sdvt_stuck_items", "sdvt_exited_items"), - [ - (1, 1, 1, 1), - (1, 1, 1, 0), - (1, 1, 0, 1), - (1, 1, 0, 0), - (1, 0, 1, 1), - (1, 0, 1, 0), - (1, 0, 0, 1), - (1, 0, 0, 0), - (0, 1, 1, 1), - (0, 1, 1, 0), - (0, 1, 0, 1), - (0, 1, 0, 0), - (0, 0, 1, 1), - (0, 0, 1, 0), - (0, 0, 0, 1), - ] -) -def test_extra_data_full_items( - voting_eoa, evm_script_executor_eoa, nor, sdvt, extra_data_service, - nor_stuck_items, nor_exited_items, sdvt_stuck_items, sdvt_exited_items, stranger -): - max_node_operators_per_item = MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM - new_keys_per_operator = 2 - +@pytest.fixture(scope="module") +def prepare_modules(nor, sdvt, voting_eoa, agent_eoa, evm_script_executor_eoa): # Fill NOR with new operators and keys (nor_count_before, added_nor_operators_count) = fill_nor_with_old_and_new_operators( nor, voting_eoa, evm_script_executor_eoa, - new_keys_per_operator, - nor_stuck_items, - nor_exited_items, - max_node_operators_per_item, + NEW_KEYS_PER_OPERATOR, + MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, ) - # Fill SimpleDVT with new operators and keys (sdvt_count_before, added_sdvt_operators_count) = fill_nor_with_old_and_new_operators( sdvt, voting_eoa, + agent_eoa, evm_script_executor_eoa, - new_keys_per_operator, - sdvt_stuck_items, - sdvt_exited_items, - max_node_operators_per_item, + NEW_KEYS_PER_OPERATOR, + MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, ) + # Fill CSM with new operators and keys + csm_operators_count = MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM + csm_count_before, added_csm_operators_count = fill_csm_operators_with_keys(csm_operators_count, + NEW_KEYS_PER_OPERATOR) + # Deposit for new added keys from buffer keys_for_sdvt = (added_sdvt_operators_count * new_keys_per_operator) + (sdvt_count_before * new_keys_per_operator) keys_for_nor = (added_nor_operators_count * new_keys_per_operator) + (nor_count_before * new_keys_per_operator) + keys_for_csm = (added_csm_operators_count * new_keys_per_operator) + (csm_count_before * new_keys_per_operator) deposit_buffer_for_keys( contracts.staking_router, + keys_for_nor, keys_for_sdvt, - keys_for_nor + keys_for_csm, ) + +@pytest.mark.parametrize("nor_stuck_items", [1, 0]) +@pytest.mark.parametrize("nor_exited_items", [1, 0]) +@pytest.mark.parametrize("sdvt_stuck_items", [1, 0]) +@pytest.mark.parametrize("sdvt_exited_items", [1, 0]) +@pytest.mark.parametrize("csm_stuck_items", [1, 0]) +@pytest.mark.parametrize("csm_exited_items", [1, 0]) +@pytest.mark.usefixtures("prepare_modules") +def test_extra_data_full_items( + stranger, nor, sdvt, extra_data_service, + nor_stuck_items, nor_exited_items, sdvt_stuck_items, sdvt_exited_items, csm_stuck_items, csm_exited_items +): + if (nor_stuck_items + nor_exited_items + sdvt_stuck_items + sdvt_exited_items + csm_exited_items + csm_stuck_items) == 0: + pytest.skip("No items to report in this test case") + + nor_ids = [] + for i in range(0, nor.getNodeOperatorsCount()): + if nor.getNodeOperatorIsActive(i): + nor_ids.append(i) + sdvt_ids = [] + for i in range(0, sdvt.getNodeOperatorsCount()): + if sdvt.getNodeOperatorIsActive(i): + sdvt_ids.append(i) + csm_ids = range(0, MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM) + nor_ids_exited = nor_ids[:nor_exited_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM] + nor_ids_stuck = nor_ids[:nor_stuck_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM] + sdvt_ids_exited = sdvt_ids[:sdvt_exited_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM] + sdvt_ids_stuck = sdvt_ids[:sdvt_stuck_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM] + csm_ids_exited = csm_ids[:csm_exited_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM] + csm_ids_stuck = csm_ids[:csm_stuck_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM] + # Prepare report extra data - nor_stuck = {(1, i): 1 for i in range(0, nor_stuck_items * max_node_operators_per_item)} - nor_exited = {(1, i): nor.getNodeOperatorSummary(i)['totalExitedValidators'] + 1 for i in range(0, nor_exited_items * max_node_operators_per_item)} - sdvt_stuck = {(2, i): 1 for i in range(0, sdvt_stuck_items * max_node_operators_per_item)} - sdvt_exited = {(2, i): sdvt.getNodeOperatorSummary(i)['totalExitedValidators'] + 1 for i in range(0, sdvt_exited_items * max_node_operators_per_item)} + nor_stuck = {(1, i): nor.getNodeOperatorSummary(i)['stuckValidatorsCount'] + 1 for i in nor_ids_stuck} + nor_exited = {(1, i): nor.getNodeOperatorSummary(i)['totalExitedValidators'] + 1 for i in nor_ids_exited} + sdvt_stuck = {(2, i): sdvt.getNodeOperatorSummary(i)['stuckValidatorsCount'] +1 for i in sdvt_ids_stuck} + sdvt_exited = {(2, i): sdvt.getNodeOperatorSummary(i)['totalExitedValidators'] + 1 for i in sdvt_ids_exited} + csm_stuck = {(3, i): contracts.csm.getNodeOperatorSummary(i)['stuckValidatorsCount'] + 1 for i in csm_ids_stuck} + csm_exited = {(3, i): contracts.csm.getNodeOperatorSummary(i)['totalExitedValidators'] + 1 for i in csm_ids_exited} extra_data = extra_data_service.collect( - {**nor_stuck, **sdvt_stuck}, - {**nor_exited, **sdvt_exited}, + {**nor_stuck, **sdvt_stuck, **csm_stuck}, + {**nor_exited, **sdvt_exited, **csm_exited}, MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, ) @@ -108,24 +127,31 @@ def test_extra_data_full_items( if nor_exited_items > 0: modules_with_exited.append(1) nor_exited_before = nor.getStakingModuleSummary()["totalExitedValidators"] - num_exited_validators_by_staking_module.append(nor_exited_before + (nor_exited_items * max_node_operators_per_item)) + num_exited_validators_by_staking_module.append(nor_exited_before + (nor_exited_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM)) if sdvt_exited_items > 0: modules_with_exited.append(2) sdvt_exited_before = sdvt.getStakingModuleSummary()["totalExitedValidators"] - num_exited_validators_by_staking_module.append(sdvt_exited_before + (sdvt_exited_items * max_node_operators_per_item)) - - nor_balance_shares_before = [] - for i in range(0, len(nor_stuck)): - nor_balance_shares_before.append(shares_balance(nor.getNodeOperator(i, False)["rewardAddress"])) - sdvt_balance_shares_before = [] - for i in range(0, len(sdvt_stuck)): - sdvt_balance_shares_before.append(shares_balance(sdvt.getNodeOperator(i, False)["rewardAddress"])) + num_exited_validators_by_staking_module.append(sdvt_exited_before + (sdvt_exited_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM)) + if csm_exited_items > 0: + modules_with_exited.append(3) + csm_exited_before = contracts.csm.getStakingModuleSummary()["totalExitedValidators"] + num_exited_validators_by_staking_module.append(csm_exited_before + (csm_exited_items * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM)) + + nor_balance_shares_before = {} + for i in nor_ids_stuck: + nor_balance_shares_before[i] = shares_balance(nor.getNodeOperator(i, False)["rewardAddress"]) + sdvt_balance_shares_before = {} + for i in sdvt_ids_stuck: + sdvt_balance_shares_before[i] = shares_balance(sdvt.getNodeOperator(i, False)["rewardAddress"]) + csm_balance_shares_before = {} + for i in csm_ids_stuck: + csm_balance_shares_before[i] = shares_balance(contracts.csm.getNodeOperator(i)["rewardAddress"]) # Perform report - (report_tx, _) = oracle_report( + (report_tx, extra_report_tx_list) = oracle_report( extraDataFormat=1, extraDataHashList=extra_data.extra_data_hash_list, - extraDataItemsCount=(nor_exited_items + nor_stuck_items + sdvt_exited_items + sdvt_stuck_items), + extraDataItemsCount=(nor_exited_items + nor_stuck_items + sdvt_exited_items + sdvt_stuck_items + csm_exited_items + csm_stuck_items), extraDataList=extra_data.extra_data_list, stakingModuleIdsWithNewlyExitedValidators=modules_with_exited, numExitedValidatorsByStakingModule=num_exited_validators_by_staking_module, @@ -136,12 +162,12 @@ def test_extra_data_full_items( # Check NOR exited nor_penalty_shares = 0 - for i in range(0, len(nor_exited)): + for i in nor_ids_exited: assert nor.getNodeOperatorSummary(i)["totalExitedValidators"] == nor_exited[(1, i)] # Check NOR stuck. Check penalties and rewards if len(nor_stuck) > 0: nor_rewards = [e for e in report_tx.events["TransferShares"] if e['to'] == nor.address][0]['sharesValue'] - for i in range(0, len(nor_stuck)): + for i in nor_ids_stuck: assert nor.getNodeOperatorSummary(i)["stuckValidatorsCount"] == nor_stuck[(1, i)] assert nor.isOperatorPenalized(i) == True shares_after = shares_balance(nor.getNodeOperator(i, False)["rewardAddress"]) @@ -160,12 +186,12 @@ def test_extra_data_full_items( # Check SDVT exited sdvt_penalty_shares = 0 - for i in range(0, len(sdvt_exited)): + for i in sdvt_ids_exited: assert sdvt.getNodeOperatorSummary(i)["totalExitedValidators"] == sdvt_exited[(2, i)] # Check SDVT stuck. Check penalties and rewards if len(sdvt_stuck) > 0: sdvt_rewards = [e for e in report_tx.events["TransferShares"] if e['to'] == sdvt.address][0]['sharesValue'] - for i in range(0, len(sdvt_stuck)): + for i in sdvt_ids_stuck: assert sdvt.getNodeOperatorSummary(i)["stuckValidatorsCount"] == sdvt_stuck[(2, i)] assert sdvt.isOperatorPenalized(i) == True shares_after = shares_balance(sdvt.getNodeOperator(i, False)["rewardAddress"]) @@ -179,11 +205,17 @@ def test_extra_data_full_items( ) sdvt_penalty_shares += rewards_after // 2 - if sdvt_penalty_shares > 0: # TODO: Fix below check when contains other penalized node operators assert almostEqWithDiff(sum(e['amountOfShares'] for e in sdvt_distribute_reward_tx.events["StETHBurnRequested"]), sdvt_penalty_shares, 100) + # Check CSM exited + for i in csm_ids_exited: + assert contracts.csm.getNodeOperatorSummary(i)["totalExitedValidators"] == csm_exited[(3, i)] + # Check CSM stuck + for i in csm_ids_stuck: + assert contracts.csm.getNodeOperatorSummary(i)["stuckValidatorsCount"] == csm_stuck[(3, i)] + ############################################ # HELPER FUNCTIONS ############################################ @@ -213,8 +245,27 @@ def add_nor_operators_with_keys(nor, voting_eoa: Account, evm_script_executor_eo nor.setNodeOperatorStakingLimit(no_id, keys_per_operator, {"from": evm_script_executor_eoa}) +def fill_csm_operators_with_keys(target_operators_count, keys_count): + if not contracts.csm.publicRelease(): + contracts.csm.grantRole(contracts.csm.MODULE_MANAGER_ROLE(), contracts.agent, {"from": contracts.agent}) + contracts.csm.activatePublicRelease({"from": contracts.agent}) + + csm_node_operators_before = contracts.csm.getNodeOperatorsCount() + added_operators_count = 0 + for no_id in range(0, csm_node_operators_before): + depositable_keys = contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] + if depositable_keys < keys_count: + csm_upload_keys(contracts.csm, contracts.cs_accounting, no_id, depositable_keys - keys_count) + while csm_node_operators_before + added_operators_count < target_operators_count: + node_operator = f"0xbb{str(added_operators_count).zfill(38)}" + csm_add_node_operator(contracts.csm, contracts.cs_accounting, node_operator, [], keys_count=keys_count) + added_operators_count += 1 + return csm_node_operators_before, added_operators_count + + + def fill_nor_with_old_and_new_operators( - nor, voting_eoa, evm_script_executor_eoa, new_keys_per_operator, nor_stuck_items, nor_exited_items, max_node_operators_per_item, + nor, voting_eoa, evm_script_executor_eoa, new_keys_per_operator, max_node_operators_per_item, ) -> tuple[int, int]: contracts.acl.grantPermission( contracts.voting, @@ -269,7 +320,7 @@ def fill_nor_with_old_and_new_operators( return operators_count_before, operators_count_added -def deposit_buffer_for_keys(staking_router, sdvt_keys_to_deposit, nor_keys_to_deposit): +def deposit_buffer_for_keys(staking_router, nor_keys_to_deposit, sdvt_keys_to_deposit, csm_keys_to_deposit): total_depositable_keys = 0 module_digests = staking_router.getAllStakingModuleDigests() for digest in module_digests: @@ -280,16 +331,18 @@ def deposit_buffer_for_keys(staking_router, sdvt_keys_to_deposit, nor_keys_to_de contracts.lido.removeStakingLimit({"from": contracts.voting}) fill_deposit_buffer(total_depositable_keys) keys_per_deposit = 50 + # Deposits for NOR + times = round(nor_keys_to_deposit / keys_per_deposit) + for _ in range(0, times): + contracts.lido.deposit(keys_per_deposit, 1, "0x", {"from": contracts.deposit_security_module}) # Deposits for SDVT - times = sdvt_keys_to_deposit // keys_per_deposit + times = round(sdvt_keys_to_deposit / keys_per_deposit) for _ in range(0, times): contracts.lido.deposit(keys_per_deposit, 2, "0x", {"from": contracts.deposit_security_module}) - - # Deposits for NOR - times = nor_keys_to_deposit // keys_per_deposit; + # Deposits for CSM + times = round(csm_keys_to_deposit / keys_per_deposit) for _ in range(0, times): - contracts.lido.deposit(keys_per_deposit, 1, "0x", {"from": contracts.deposit_security_module}) - + contracts.lido.deposit(keys_per_deposit, 3, "0x", {"from": contracts.deposit_security_module}) def calc_no_rewards(module, no_id, shares_minted_as_fees): operator_summary = module.getNodeOperatorSummary(no_id) diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py index f08141d83..1a1ae53fa 100644 --- a/tests/regression/test_csm.py +++ b/tests/regression/test_csm.py @@ -21,6 +21,7 @@ CSM_MODULE_ID = 3 +pytestmark = pytest.mark.usefixtures("autoexecute_vote_ms") @pytest.fixture(scope="module") def csm(): @@ -199,8 +200,7 @@ def test_csm_get_staking_module_summary(csm, accounting, node_operator, extra_da deposits_count = 3 new_keys = 5 new_depositable = new_keys - deposits_count - address, _ = get_ea_member() - csm_upload_keys(csm, accounting, node_operator, address, new_keys) + csm_upload_keys(csm, accounting, node_operator, new_keys) fill_deposit_buffer(deposits_count) contracts.lido.deposit(deposits_count, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module}) diff --git a/tests/regression/test_staking_router_stake_distribution.py b/tests/regression/test_staking_router_stake_distribution.py index de1174ced..f827a7221 100644 --- a/tests/regression/test_staking_router_stake_distribution.py +++ b/tests/regression/test_staking_router_stake_distribution.py @@ -111,7 +111,7 @@ def assure_depositable_keys(stranger): fill_simple_dvt_ops_vetted_keys(stranger, 3, 5) if not modules[3].depositable_keys: address, proof = get_ea_member() - csm_add_node_operator(contracts.csm, contracts.cs_accounting, address, proof) + csm_add_node_operator(contracts.csm, contracts.cs_accounting, address, proof, curve_id=contracts.cs_early_adoption.CURVE_ID()) def test_stake_distribution(stranger): """ diff --git a/utils/node_operators.py b/utils/node_operators.py index 09848e33e..43715126f 100644 --- a/utils/node_operators.py +++ b/utils/node_operators.py @@ -49,4 +49,3 @@ def encode_add_operator_lido(address, name): def deactivate_node_operator(id: int) -> Tuple[str, str]: curated_sm = contracts.node_operators_registry return (curated_sm.address, curated_sm.deactivateNodeOperator.encode_input(id)) - diff --git a/utils/test/csm_helpers.py b/utils/test/csm_helpers.py index 56f23b67d..b93b641bb 100644 --- a/utils/test/csm_helpers.py +++ b/utils/test/csm_helpers.py @@ -1,6 +1,7 @@ from brownie import ZERO_ADDRESS -from utils.balance import set_balance +from utils.balance import set_balance_in_wei +from utils.test.helpers import ETH from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch @@ -8,7 +9,7 @@ def get_ea_member(): """ Random address and proof for EA member """ - address = set_balance("0x00200f4e638e81ebe172daa18c9193a33a50bbbd", 100000) + address = "0x00200f4e638e81ebe172daa18c9193a33a50bbbd" proof = ["0x6afc021ded39a008e9e7c646cd70b0e0425b8c0cc2decc102d45a09a9cadc3b4", "0x9fb8ad314dcef15562b7a930e037068f77bb860156199862df2957017d68b59b", "0xa70999dbf9fb0843abbcfbc67498e195527ac129b43994dfaccdde3479893bed", @@ -26,10 +27,13 @@ def get_ea_member(): return address, proof -def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5): +def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5, curve_id=0): pubkeys_batch = random_pubkeys_batch(keys_count) signatures_batch = random_signatures_batch(keys_count) - curve_id = 1 # EA curve + + value = accounting.getBondAmountByKeysCount['uint256,uint256'](keys_count, curve_id) + set_balance_in_wei(node_operator, value + ETH(1)) + csm.addNodeOperatorETH( keys_count, pubkeys_batch, @@ -37,15 +41,16 @@ def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5): (ZERO_ADDRESS, ZERO_ADDRESS, False), proof, ZERO_ADDRESS, - {"from": node_operator, "value": accounting.getBondAmountByKeysCount['uint256,uint256'](keys_count, curve_id)} + {"from": node_operator, "value": value} ) return csm.getNodeOperatorsCount() - 1 -def csm_upload_keys(csm, accounting, no_id, node_operator, keys_count=5): +def csm_upload_keys(csm, accounting, no_id, keys_count=5): + manager_address = csm.getNodeOperator(no_id)["managerAddress"] pubkeys_batch = random_pubkeys_batch(keys_count) signatures_batch = random_signatures_batch(keys_count) csm.addValidatorKeysETH(no_id, keys_count, pubkeys_batch, signatures_batch, - {"from": node_operator, "value": accounting.getRequiredBondForNextKeys(no_id, keys_count)} + {"from": manager_address, "value": accounting.getRequiredBondForNextKeys(no_id, keys_count)} ) From ccbacb889654d130b6ff002cbc2371d27634f609 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Fri, 27 Sep 2024 16:32:52 +0500 Subject: [PATCH 125/220] added test for worst extra data report in terms of gas usage --- ...accounting_oracle_extra_data_full_items.py | 89 +++++++++++++++++-- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index dcdfe671a..f5a36e8c6 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -1,3 +1,5 @@ +from math import ceil + import pytest from brownie import convert from brownie.network.account import Account @@ -177,7 +179,7 @@ def test_extra_data_full_items( assert almostEqWithDiff( shares_after - nor_balance_shares_before[i], rewards_after // 2, - 1, + 2, ) nor_penalty_shares += rewards_after // 2 @@ -201,7 +203,7 @@ def test_extra_data_full_items( assert almostEqWithDiff( shares_after - sdvt_balance_shares_before[i], rewards_after // 2, - 1, + 2, ) sdvt_penalty_shares += rewards_after // 2 @@ -216,6 +218,82 @@ def test_extra_data_full_items( for i in csm_ids_stuck: assert contracts.csm.getNodeOperatorSummary(i)["stuckValidatorsCount"] == csm_stuck[(3, i)] + +def test_extra_data_most_expensive_report(autoexecute_vote_ms, extra_data_service): + """ + Make sure the worst report fits into the block gas limit. + It needs to prepare a lot of node operators in a very special state, so it takes a lot of time to run. + + N = oracle limit + - Create N NOs + - Deposit all keys + - Upload +1 key for each NO + - Create New NO with 1 key + - Stuck N NOs + - Deposit 1 key from NO N+1 (to exclude batches from the queue) + - Unstuck N NOs + + An estimate for 8 * 24 items: + Gas used: 11850807 (39.50%) + """ + + csm_operators_count = MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION * MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM + # create or ensure there are max node operators with 1 depositable key + fill_csm_operators_with_keys(csm_operators_count,1) + depositable_keys = contracts.csm.getStakingModuleSummary()["depositableValidatorsCount"] + deposit_buffer_for_keys(contracts.staking_router, 0, 0, depositable_keys) + assert contracts.csm.getStakingModuleSummary()["depositableValidatorsCount"] == 0 + + csm_ids = range(0, csm_operators_count) + # Upload a new key for each node operator to put them into the queue + for i in csm_ids: + csm_upload_keys(contracts.csm, contracts.cs_accounting, i, 1) + assert contracts.csm.getNodeOperator(i)["depositableValidatorsCount"] == 1 + # Add a new node operator with 1 depositable key to the end of the queue + last_no_id = csm_add_node_operator(contracts.csm, contracts.cs_accounting, f"0xbb{str(csm_operators_count).zfill(38)}", [], keys_count=1) + # report stuck keys for all node operators + extra_data = extra_data_service.collect( + {(3, i): 1 for i in range(csm_operators_count)}, + {}, + MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, + ) + + oracle_report( + extraDataFormat=1, + extraDataHashList=extra_data.extra_data_hash_list, + extraDataItemsCount=MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + extraDataList=extra_data.extra_data_list, + ) + + # Check CSM stuck + for i in csm_ids: + assert contracts.csm.getNodeOperatorSummary(i)["stuckValidatorsCount"] == 1 + # deposit last node operator's key + deposit_buffer_for_keys(contracts.staking_router, 0, 0, 1) + assert contracts.csm.getNodeOperator(last_no_id)["totalDepositedKeys"] == 1 + + # report unstuck keys for all node operators + + extra_data = extra_data_service.collect( + {(3, i): 0 for i in range(csm_operators_count)}, + {}, + MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, + ) + + oracle_report( + extraDataFormat=1, + extraDataHashList=extra_data.extra_data_hash_list, + extraDataItemsCount=MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + extraDataList=extra_data.extra_data_list, + ) + + # Check CSM unstuck + for i in csm_ids: + assert contracts.csm.getNodeOperatorSummary(i)["stuckValidatorsCount"] == 0 + + ############################################ # HELPER FUNCTIONS ############################################ @@ -256,6 +334,7 @@ def fill_csm_operators_with_keys(target_operators_count, keys_count): depositable_keys = contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] if depositable_keys < keys_count: csm_upload_keys(contracts.csm, contracts.cs_accounting, no_id, depositable_keys - keys_count) + assert contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] == keys_count while csm_node_operators_before + added_operators_count < target_operators_count: node_operator = f"0xbb{str(added_operators_count).zfill(38)}" csm_add_node_operator(contracts.csm, contracts.cs_accounting, node_operator, [], keys_count=keys_count) @@ -332,15 +411,15 @@ def deposit_buffer_for_keys(staking_router, nor_keys_to_deposit, sdvt_keys_to_de fill_deposit_buffer(total_depositable_keys) keys_per_deposit = 50 # Deposits for NOR - times = round(nor_keys_to_deposit / keys_per_deposit) + times = ceil(nor_keys_to_deposit / keys_per_deposit) for _ in range(0, times): contracts.lido.deposit(keys_per_deposit, 1, "0x", {"from": contracts.deposit_security_module}) # Deposits for SDVT - times = round(sdvt_keys_to_deposit / keys_per_deposit) + times = ceil(sdvt_keys_to_deposit / keys_per_deposit) for _ in range(0, times): contracts.lido.deposit(keys_per_deposit, 2, "0x", {"from": contracts.deposit_security_module}) # Deposits for CSM - times = round(csm_keys_to_deposit / keys_per_deposit) + times = ceil(csm_keys_to_deposit / keys_per_deposit) for _ in range(0, times): contracts.lido.deposit(keys_per_deposit, 3, "0x", {"from": contracts.deposit_security_module}) From baf5dc74506b13e7a4abf5b99bfb695cbd9152b4 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Thu, 3 Oct 2024 14:20:17 +0500 Subject: [PATCH 126/220] upd merkle proof --- utils/test/csm_helpers.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/utils/test/csm_helpers.py b/utils/test/csm_helpers.py index b93b641bb..8df52baab 100644 --- a/utils/test/csm_helpers.py +++ b/utils/test/csm_helpers.py @@ -10,20 +10,21 @@ def get_ea_member(): Random address and proof for EA member """ address = "0x00200f4e638e81ebe172daa18c9193a33a50bbbd" - proof = ["0x6afc021ded39a008e9e7c646cd70b0e0425b8c0cc2decc102d45a09a9cadc3b4", - "0x9fb8ad314dcef15562b7a930e037068f77bb860156199862df2957017d68b59b", - "0xa70999dbf9fb0843abbcfbc67498e195527ac129b43994dfaccdde3479893bed", - "0xe529a4c4315a65bc576d6cb030bb0f6957084d18fb108d8bb2d2b9ac05b17d66", - "0xc94fe8c075792d6610715e8adbc53fafd06aeddaeb4fcb45867d8ab92685bbe6", - "0xb2cc15dba514f0df05e7243a48aa47b1a5455f5a4291398c0edacca5f0aca2fc", - "0x7c4efc55c91a8f3b6064dcdb0622d9815dc31998fc6f9069a6ba0188512f1144", - "0xcb497013c0ad8e40663b8318967dcbc1cfbb38132a5bb36a6def0bf1352b3733", - "0xab3d7faaf4662097e8a953ee63af9e71078a4224c4c69425b6c53404aa14459f", - "0x9e1485ad05559cc88dc80939a490c03bbdb7aa81c01b259023c7cdc73884dabc", - "0x6206a54be4267fcced2b6c60e90b9f1974933b4655444a56ae993d4727bacde4", - "0x60aaa2f08de8edbe2b9edfb201c5ed962cbbd8ce1d096013549fc4de2dc330d6", - "0xd88ad1a0d41adf346661f16fad68e45102a5f7730122af03c81bdc90a6b473d7", - "0x9abd3efc8d538c4714dae174a75caaa1414c9a9155e8cea71e977822978807df"] + proof = ["0x6afb48863bdb84141ef424715c70cd61e5d629a293038b2e55b2aaa330955435", + "0xf2cbc3e761642defc881539fb26fd2f349c87ac9baa031572693d4b47286d521", + "0x526c3d791066e220842b26d606a332cc22d088eb0d1431c43d6c5a8503417f4e", + "0x25f371f22e592b9541b1fe8c3e2a599b3db0b11e9b027bffe525dc48b6971bf5", + "0xffaad8403c4681c00ce2a7d6c82f2f4343ec7ef0efd9dd1959e37a55c71949bc", + "0xf86d0c08277b41ad7d4b9640be4c1e6b0e2eed1fd4bfc084c300086cb638b933", + "0x3c66b0db484c5bd7351114a5e7fb073604fd8772254ad3ef02432918a7b65f2c", + "0x47d2ab6d81d882809ffb9df212c126fbbb5fe01c0849cb42d8101fe0f5b5ea1c", + "0x62373951ea824814af660ae6276d03fec5e734f9ea8e9fe662e600b19fd58dea", + "0x812242ec081e8ebf25e682ff968a40dbf0786caa89ba18958d7f91f7e981e415", + "0x1b3e4aade81953dbfc7df20d22852a95c255bf0bcf5f186115f9f439b29f4845", + "0x2db100e320128d95cf46a003497bc5dcf25cdc62a1e66a89f0fa7c79b1a858ad", + "0x03d33582f7cac74515d95d4ab3711d95ce9814df7351a1a46223d3bb4c3fdd44", + "0x566d2db5a4091a4c3152e2e3ba7a26d44b9f09515d4d8e587cf7f8aea77e38f0", + "0xd415d9673b0b81ccf04e5ed1317f6a2ec5c94bc3c8d14e5d302225ad9b99b137"] return address, proof From 07f3bb497d5c60f3399a70bee61f40aba07c3095 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Thu, 3 Oct 2024 15:19:32 +0500 Subject: [PATCH 127/220] fix conflicts fix flaky tests --- tests/acceptance/test_csm.py | 2 +- ...test_accounting_oracle_extra_data_full_items.py | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/acceptance/test_csm.py b/tests/acceptance/test_csm.py index 3ae8699d4..357268c09 100644 --- a/tests/acceptance/test_csm.py +++ b/tests/acceptance/test_csm.py @@ -181,7 +181,7 @@ def test_initial_state(self, hash_consensus): # assert hash_consensus.getInitialRefSlot() > 5254400 members = hash_consensus.getMembers() - assert members["addresses"] == ORACLE_COMMITTEE + assert sorted(members["addresses"]) == sorted(ORACLE_COMMITTEE) assert hash_consensus.getReportProcessor() == CS_FEE_ORACLE_ADDRESS diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index f5a36e8c6..70a83f043 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -17,8 +17,6 @@ NEW_KEYS_PER_OPERATOR = 2 -pytestmark = pytest.mark.usefixtures("autoexecute_vote_ms") - @pytest.fixture(scope="module") def voting_eoa(accounts): return accounts.at(contracts.voting.address, force=True) @@ -45,7 +43,7 @@ def sdvt(interface): @pytest.fixture(scope="module") -def prepare_modules(nor, sdvt, voting_eoa, agent_eoa, evm_script_executor_eoa): +def prepare_modules(nor, sdvt, voting_eoa, agent_eoa, evm_script_executor_eoa, autoexecute_vote_ms): # Fill NOR with new operators and keys (nor_count_before, added_nor_operators_count) = fill_nor_with_old_and_new_operators( nor, @@ -58,7 +56,6 @@ def prepare_modules(nor, sdvt, voting_eoa, agent_eoa, evm_script_executor_eoa): (sdvt_count_before, added_sdvt_operators_count) = fill_nor_with_old_and_new_operators( sdvt, voting_eoa, - agent_eoa, evm_script_executor_eoa, NEW_KEYS_PER_OPERATOR, MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM, @@ -70,9 +67,9 @@ def prepare_modules(nor, sdvt, voting_eoa, agent_eoa, evm_script_executor_eoa): NEW_KEYS_PER_OPERATOR) # Deposit for new added keys from buffer - keys_for_sdvt = (added_sdvt_operators_count * new_keys_per_operator) + (sdvt_count_before * new_keys_per_operator) - keys_for_nor = (added_nor_operators_count * new_keys_per_operator) + (nor_count_before * new_keys_per_operator) - keys_for_csm = (added_csm_operators_count * new_keys_per_operator) + (csm_count_before * new_keys_per_operator) + keys_for_sdvt = (added_sdvt_operators_count * NEW_KEYS_PER_OPERATOR) + (sdvt_count_before * NEW_KEYS_PER_OPERATOR) + keys_for_nor = (added_nor_operators_count * NEW_KEYS_PER_OPERATOR) + (nor_count_before * NEW_KEYS_PER_OPERATOR) + keys_for_csm = (added_csm_operators_count * NEW_KEYS_PER_OPERATOR) + (csm_count_before * NEW_KEYS_PER_OPERATOR) deposit_buffer_for_keys( contracts.staking_router, keys_for_nor, @@ -355,8 +352,7 @@ def fill_nor_with_old_and_new_operators( # Calculate new operators count operators_count_before = nor.getNodeOperatorsCount() - operators_count_wanted = max(nor_stuck_items, nor_exited_items) * max_node_operators_per_item - operators_count_after = max(operators_count_wanted, operators_count_before) + operators_count_after = max(max_node_operators_per_item, operators_count_before) operators_count_added = max(operators_count_after - operators_count_before, 0) # Add new node operators and keys From 2d11f02c3fe5448c9ed97e0b9cf97786467eb638 Mon Sep 17 00:00:00 2001 From: maksim Date: Thu, 3 Oct 2024 15:02:55 +0200 Subject: [PATCH 128/220] feat: add csm delploy params --- configs/config_mainnet.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index ef31f3685..7f93f0763 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -323,3 +323,25 @@ TRP_FACTORY_DEPLOY_BLOCK_NUMBER = 16540381 SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" + +#CSM +CS_ORACLE_EPOCHS_PER_FRAME = 225 * 7 # 7 days +CS_MODULE_ID = 3 +CS_MODULE_NAME = "Community Staking" +CS_MODULE_MODULE_FEE_BP = 600 +CS_MODULE_TREASURY_FEE_BP = 400 +CS_MODULE_TARGET_SHARE_BP = 100 +CS_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 100 +CS_MODULE_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE = 25 + +# ToDo: update after deploy +CSM_ADDRESS = "0xbc8eCccb89650c3E796e803CB009BF9b898CB359" +CS_ACCOUNTING_ADDRESS = "0x4B0FccF53589c1F185B35db88bB315a0bBF9a3e0" +CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xD537bF4b795b7D07Bd5F4bAf7017e3ce8360B1DE" +CS_EARLY_ADOPTION_ADDRESS = "0x1aa96efd2B002541E830CB7f60e473AA24e31F9A" +CS_FEE_DISTRIBUTOR_ADDRESS = "0x5847798CE8c89e3Fff59AE5fA30BEC0d406b5687" +CS_FEE_ORACLE_ADDRESS = "0x4e3E7dC9D84dA7BE8f017f4C36153A61341736d4" +CS_GATE_SEAL_ADDRESS = "0x5cFCa30450B1e5548F140C24A47E36c10CE306F0" +CS_VERIFIER_ADDRESS = "0x0C60536783db9ED5A2B216970B10FF2243d317dD" + From 7babcf1db6e0ebecfd26ae8d0cfbf8f67b6c24a5 Mon Sep 17 00:00:00 2001 From: VP Date: Thu, 3 Oct 2024 17:50:11 +0200 Subject: [PATCH 129/220] test: fix negative rebase for multiple staking modules --- .../test_neg_rebase_sanity_checks.py | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/tests/regression/test_neg_rebase_sanity_checks.py b/tests/regression/test_neg_rebase_sanity_checks.py index d50222df8..d551ff121 100644 --- a/tests/regression/test_neg_rebase_sanity_checks.py +++ b/tests/regression/test_neg_rebase_sanity_checks.py @@ -16,45 +16,61 @@ def oracle_report_sanity_checker() -> Contract: return contracts.oracle_report_sanity_checker -def test_negative_rebase_correct_exited_validators_count(oracle_report_sanity_checker): +def test_negative_rebase_correct_exited_validators_count_pos_rebase(oracle_report_sanity_checker): locator = contracts.lido_locator assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() - reported_validators_count = exited_validators_count() + 2 - print(f'reported_validators_count: {reported_validators_count}') + reported_validators = exited_validators_count() - oracle_report(cl_diff=-ETH(40000), stakingModuleIdsWithNewlyExitedValidators=[1], - numExitedValidatorsByStakingModule=[reported_validators_count]) + reported_validators_values = [value + 2 for value in reported_validators.values()] + oracle_report(cl_diff=ETH(300), stakingModuleIdsWithNewlyExitedValidators=list(reported_validators.keys()), + numExitedValidatorsByStakingModule=reported_validators_values) count = oracle_report_sanity_checker.getReportDataCount() assert count > 0 (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) - assert storedExitedValidators == reported_validators_count + assert storedExitedValidators == sum(reported_validators_values) -def test_negative_rebase_more_than_54_reports(oracle_report_sanity_checker): +def test_negative_rebase_correct_exited_validators_count_neg_rebase(oracle_report_sanity_checker): locator = contracts.lido_locator assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() - reported_validators_count = exited_validators_count() + 2 - print(f'reported_validators_count: {reported_validators_count}') + reported_validators = exited_validators_count() + + reported_validators_values = [value + 3 for value in reported_validators.values()] + oracle_report(cl_diff=-ETH(40000), stakingModuleIdsWithNewlyExitedValidators=list(reported_validators.keys()), + numExitedValidatorsByStakingModule=reported_validators_values) + + count = oracle_report_sanity_checker.getReportDataCount() + assert count > 0 + (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) + + assert storedExitedValidators == sum(reported_validators_values) + +def test_negative_rebase_more_than_54_reports(oracle_report_sanity_checker): + locator = contracts.lido_locator + assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() + reported_validators_values = exited_validators_count().values() for _ in range(58): - reported_validators_count += 3 - oracle_report(cl_diff=-ETH(400), stakingModuleIdsWithNewlyExitedValidators=[1], - numExitedValidatorsByStakingModule=[reported_validators_count]) + reported_validators_values = [value + 3 for value in reported_validators_values] + oracle_report(cl_diff=-ETH(400), stakingModuleIdsWithNewlyExitedValidators=exited_validators_count().keys(), + numExitedValidatorsByStakingModule=reported_validators_values) count = oracle_report_sanity_checker.getReportDataCount() assert count > 0 (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) - assert storedExitedValidators == reported_validators_count + assert storedExitedValidators == sum(reported_validators_values) def exited_validators_count(): + assert contracts.lido_locator.stakingRouter() == contracts.staking_router ids = contracts.staking_router.getStakingModuleIds() - exited = 0 + print(f'ids: {ids}') + exited = {} for id in ids: - exited += contracts.staking_router.getStakingModule(id)["exitedValidatorsCount"] + exited[id] = contracts.staking_router.getStakingModule(id)["exitedValidatorsCount"] return exited From 879ea9aaf3a148f99f953f76a0d984ecd454c9df Mon Sep 17 00:00:00 2001 From: VP Date: Thu, 3 Oct 2024 18:13:59 +0200 Subject: [PATCH 130/220] test: second opinion oracle is zero address --- tests/acceptance/test_oracle_report_sanity_checker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/acceptance/test_oracle_report_sanity_checker.py b/tests/acceptance/test_oracle_report_sanity_checker.py index 3e6b222c2..85ad6d57a 100644 --- a/tests/acceptance/test_oracle_report_sanity_checker.py +++ b/tests/acceptance/test_oracle_report_sanity_checker.py @@ -17,6 +17,7 @@ INACTIVITY_PENALTIES_AMOUNT_PWEI, CL_BALANCE_ORACLES_ERROR_UPPER_BP_LIMIT ) +from utils.test.helpers import ZERO_ADDRESS # Source of truth: https://hackmd.io/pdix1r4yR46fXUqiHaNKyw?view expected_report_limits = { @@ -46,6 +47,7 @@ def test_links(contract): def test_limits(contract): assert contract.getMaxPositiveTokenRebase() == expected_report_limits["maxPositiveTokenRebase"] - limits = contract.getOracleReportLimits() + assert contract.secondOpinionOracle() == ZERO_ADDRESS + limits = contract.getOracleReportLimits() assert dict(zip(expected_report_limits.keys(), limits)) == expected_report_limits From f7a3133203eb095d22720292d7b725d5977ce0df Mon Sep 17 00:00:00 2001 From: VP Date: Fri, 4 Oct 2024 09:15:21 +0200 Subject: [PATCH 131/220] test: block large negative rebase --- .../test_neg_rebase_sanity_checks.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/regression/test_neg_rebase_sanity_checks.py b/tests/regression/test_neg_rebase_sanity_checks.py index d551ff121..a3b315e78 100644 --- a/tests/regression/test_neg_rebase_sanity_checks.py +++ b/tests/regression/test_neg_rebase_sanity_checks.py @@ -1,5 +1,6 @@ import pytest from brownie import Contract, web3, reverts, accounts, chain # type: ignore +from utils.evm_script import encode_error from utils.test.exit_bus_data import LidoValidator from utils.test.extra_data import ExtraDataService from utils.test.oracle_report_helpers import ( @@ -11,6 +12,10 @@ contracts, ) +INITIAL_SLASHING_AMOUNT_PWEI = 1000 +INACTIVITY_PENALTIES_AMOUNT_PWEI = 101 +ONE_PWEI = ETH(0.001) + @pytest.fixture(scope="module") def oracle_report_sanity_checker() -> Contract: return contracts.oracle_report_sanity_checker @@ -48,6 +53,18 @@ def test_negative_rebase_correct_exited_validators_count_neg_rebase(oracle_repor assert storedExitedValidators == sum(reported_validators_values) +def test_blocked_huge_negative_rebase(oracle_report_sanity_checker): + locator = contracts.lido_locator + assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() + + (_, cl_validators, cl_balance) = contracts.lido.getBeaconStat() + + max_cl_balance = (INITIAL_SLASHING_AMOUNT_PWEI + INACTIVITY_PENALTIES_AMOUNT_PWEI) * ONE_PWEI * cl_validators + error_cl_decrease = cl_balance // 10 # 10% of current balance will lead to error + print("max_cl_balance", max_cl_balance) + with reverts(encode_error("IncorrectCLBalanceDecrease(uint256, uint256)", [error_cl_decrease, max_cl_balance])): + oracle_report(cl_diff=-error_cl_decrease, exclude_vaults_balances=True, silent=True) + def test_negative_rebase_more_than_54_reports(oracle_report_sanity_checker): locator = contracts.lido_locator assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() @@ -68,7 +85,6 @@ def test_negative_rebase_more_than_54_reports(oracle_report_sanity_checker): def exited_validators_count(): assert contracts.lido_locator.stakingRouter() == contracts.staking_router ids = contracts.staking_router.getStakingModuleIds() - print(f'ids: {ids}') exited = {} for id in ids: exited[id] = contracts.staking_router.getStakingModule(id)["exitedValidatorsCount"] From 663c02f3679d6ea8627e3dbe013f431c6ee1299a Mon Sep 17 00:00:00 2001 From: VP Date: Fri, 4 Oct 2024 09:26:46 +0200 Subject: [PATCH 132/220] test: fix code style --- tests/regression/test_neg_rebase_sanity_checks.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/regression/test_neg_rebase_sanity_checks.py b/tests/regression/test_neg_rebase_sanity_checks.py index a3b315e78..ca46b55ee 100644 --- a/tests/regression/test_neg_rebase_sanity_checks.py +++ b/tests/regression/test_neg_rebase_sanity_checks.py @@ -33,9 +33,9 @@ def test_negative_rebase_correct_exited_validators_count_pos_rebase(oracle_repor count = oracle_report_sanity_checker.getReportDataCount() assert count > 0 - (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) + (_, stored_exited_validators, _) = oracle_report_sanity_checker.reportData(count - 1) - assert storedExitedValidators == sum(reported_validators_values) + assert stored_exited_validators == sum(reported_validators_values) def test_negative_rebase_correct_exited_validators_count_neg_rebase(oracle_report_sanity_checker): locator = contracts.lido_locator @@ -77,9 +77,9 @@ def test_negative_rebase_more_than_54_reports(oracle_report_sanity_checker): count = oracle_report_sanity_checker.getReportDataCount() assert count > 0 - (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) + (_, stored_exited_validators, _) = oracle_report_sanity_checker.reportData(count - 1) - assert storedExitedValidators == sum(reported_validators_values) + assert stored_exited_validators == sum(reported_validators_values) def exited_validators_count(): From 78757369fbc665a6c99fda44545f08d666825c5e Mon Sep 17 00:00:00 2001 From: VP Date: Fri, 4 Oct 2024 09:27:11 +0200 Subject: [PATCH 133/220] test: negative balance stored correctly --- .../test_neg_rebase_sanity_checks.py | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/regression/test_neg_rebase_sanity_checks.py b/tests/regression/test_neg_rebase_sanity_checks.py index ca46b55ee..92840cda6 100644 --- a/tests/regression/test_neg_rebase_sanity_checks.py +++ b/tests/regression/test_neg_rebase_sanity_checks.py @@ -49,9 +49,30 @@ def test_negative_rebase_correct_exited_validators_count_neg_rebase(oracle_repor count = oracle_report_sanity_checker.getReportDataCount() assert count > 0 - (_, storedExitedValidators, _) = oracle_report_sanity_checker.reportData(count - 1) + (_, stored_exited_validators, _) = oracle_report_sanity_checker.reportData(count - 1) + + assert stored_exited_validators == sum(reported_validators_values) + +def test_negative_rebase_correct_balance_neg_rebase(oracle_report_sanity_checker): + locator = contracts.lido_locator + assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() + + cl_decrease = ETH(40000) + oracle_report(cl_diff=-cl_decrease, exclude_vaults_balances=True) + + count = oracle_report_sanity_checker.getReportDataCount() + assert count > 0 + (_, _, cl_balance) = oracle_report_sanity_checker.reportData(count - 1) + assert cl_balance == cl_decrease + + cl_decrease2 = ETH(30000) + oracle_report(cl_diff=-cl_decrease2, exclude_vaults_balances=True) + count = oracle_report_sanity_checker.getReportDataCount() + assert count > 0 + (_, _, cl_balance) = oracle_report_sanity_checker.reportData(count - 1) + + assert cl_balance == cl_decrease2 - assert storedExitedValidators == sum(reported_validators_values) def test_blocked_huge_negative_rebase(oracle_report_sanity_checker): locator = contracts.lido_locator From 0bcd0862036ce5beed9f404f59a9a8e3f9572684 Mon Sep 17 00:00:00 2001 From: VP Date: Fri, 4 Oct 2024 09:30:39 +0200 Subject: [PATCH 134/220] test: split second opinion is empty test --- tests/acceptance/test_oracle_report_sanity_checker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/acceptance/test_oracle_report_sanity_checker.py b/tests/acceptance/test_oracle_report_sanity_checker.py index 85ad6d57a..c9d5f2ce1 100644 --- a/tests/acceptance/test_oracle_report_sanity_checker.py +++ b/tests/acceptance/test_oracle_report_sanity_checker.py @@ -47,7 +47,9 @@ def test_links(contract): def test_limits(contract): assert contract.getMaxPositiveTokenRebase() == expected_report_limits["maxPositiveTokenRebase"] - assert contract.secondOpinionOracle() == ZERO_ADDRESS limits = contract.getOracleReportLimits() assert dict(zip(expected_report_limits.keys(), limits)) == expected_report_limits + +def test_second_opinion_is_empty(contract): + assert contract.secondOpinionOracle() == ZERO_ADDRESS From cb41789ee52d0c870f648ab7940e8fae95c41728 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Fri, 4 Oct 2024 11:39:19 +0400 Subject: [PATCH 135/220] fix: sr+csm vote description --- scripts/vote_sr_v2.py | 107 +++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/scripts/vote_sr_v2.py b/scripts/vote_sr_v2.py index 006f01680..3da7cf04e 100644 --- a/scripts/vote_sr_v2.py +++ b/scripts/vote_sr_v2.py @@ -1,34 +1,33 @@ """ -SR V2 -1. Update locator implementation -2. Revoke pause role from old DSM -3. Revoke resume role from old DSM -4. Grant unvetting role to new DSM -5. Update SR implementation -6. Call finalize upgrade on SR -7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo -8. Update `NodeOperatorsRegistry` implementation -9. Finalize NOR upgrade -10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo -11. Update `SimpleDVT` implementation +Staking Router V2 +1. Update Locator implementation +2. Revoke pause role from old Deposit Security Module +3. Revoke resume role from old Deposit Security Module +4. Grant unvetting role to new Deposit Security Module +5. Update Staking Router implementation +6. Call finalize upgrade on Staking Router +7. Publish new Node Operators Registry implementation in Node Operators Registry app APM repo +8. Update Node Operators Registry implementation +9. Finalize Node Operators Registry upgrade +10. Publish new SimpleDVT implementation in SimpleDVT app APM repo +11. Update SimpleDVT implementation 12. Finalize SimpleDVT upgrade -13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}` -14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}` -15. Grant manage consensus role to agent ${AGENT}` -16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}` -17. Revoke manage consensus role from agent ${AGENT} -18. Remove old target limit factory -19. Add Target limit for SDVT factory to ET - -CSM - -20. Add staking module -21. Grant request burn role to CSAccounting contract -22. Grant resume role to agent -23. Resume staking module -24. Revoke resume role from agent -25. Update initial epoch -26. Add CS settle EL stealing factory to ET +13. Update Accounting Oracle implementation +14. Finalize Accounting Oracle upgrade and update consensus version +15. Grant manage consensus role to Aragon Agent +16. Update Validator Exit Bus Oracle consensus version +17. Revoke manage consensus role from Aragon Agent +18. Remove old UpdateTargetValidatorLimits for SimpleDVT factory from EasyTrack +19. Add new UpdateTargetValidatorLimits for SimpleDVT factory to EasyTrack + +Community Staking Module +20. Add Community Staking Module to Staking Router +21. Grant request burn role to CSAccounting +22. Grant resume role to Aragon Agent +23. Resume Community Staking Module +24. Revoke resume role from Aragon Agent +25. Update initial epoch on CSHashConsensus +26. Add CSMSettleElStealingPenalty factory to EasyTrack """ import time @@ -191,11 +190,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # SR 2 # ( - "1. Update locator implementation", + "1. Update Locator implementation", agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), ), ( - "2. Revoke pause role from old DSM", + "2. Revoke pause role from old Deposit Security Module", agent_forward( [ encode_oz_revoke_role( @@ -207,7 +206,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "3. Revoke resume role from old DSM", + "3. Revoke resume role from old Deposit Security Module", agent_forward( [ encode_oz_revoke_role( @@ -219,7 +218,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "4. Grant unvetting role to new DSM", + "4. Grant unvetting role to new Deposit Security Module", agent_forward( [ encode_oz_grant_role( @@ -231,31 +230,31 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "5. Update SR implementation", + "5. Update Staking Router implementation", agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), ), ( - "6. Call finalize upgrade on SR", + "6. Call finalize upgrade on Staking Router", encode_staking_router_finalize(), ), ( - "7. Publish new `NodeOperatorsRegistry` implementation in NodeOperatorsRegistry app APM repo", + "7. Publish new Node Operators Registry implementation in Node Operators Registry app APM repo", add_implementation_to_nor_app_repo(NOR_VERSION_REPO, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), ), ( - "8. Update `NodeOperatorsRegistry` implementation", + "8. Update Node Operators Registry implementation", update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), ), ( - "9. Finalize NOR upgrade", + "9. Finalize Node Operators Registry upgrade", encode_nor_finalize(), ), ( - "10. Publish new `SimpleDVT` implementation in SimpleDVT app APM repo", + "10. Publish new SimpleDVT implementation in SimpleDVT app APM repo", add_implementation_to_sdvt_app_repo(SDVT_VERSION_REPO, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), ), ( - "11. Update `SimpleDVT` implementation", + "11. Update SimpleDVT implementation", update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), ), ( @@ -263,15 +262,15 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T encode_sdvt_finalize(), ), ( - "13. Update AO implementation to ${ACCOUNTING_ORACLE_IMPL}", + "13. Update Accounting Oracle implementation", agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), ), ( - "14. Finalize AO upgrade and set consensus version to ${AO_CONSENSUS_VERSION}", + "14. Finalize Accounting Oracle upgrade and update consensus version", encode_ao_finalize(), ), ( - "15. Grant manage consensus role to agent ${AGENT}", + "15. Grant manage consensus role to Aragon Agent", agent_forward( [ encode_oz_grant_role( @@ -283,11 +282,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "16. Update VEBO consensus version to ${VEBO_CONSENSUS_VERSION}", + "16. Update Validator Exit Bus Oracle consensus version", agent_forward([encode_set_consensus_version()]), ), ( - "17. Revoke manage consensus role from agent ${AGENT}", + "17. Revoke manage consensus role from Aragon Agent", agent_forward( [ encode_oz_revoke_role( @@ -299,13 +298,13 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "18. Remove old target limit factory", + "18. Remove old UpdateTargetValidatorLimits for SimpleDVT factory from EasyTrack", remove_evmscript_factory( factory=OLD_TARGET_LIMIT__FACTORY, ), ), ( - "19. Add Target limit for SDVT factory to ET", + "19. Add new UpdateTargetValidatorLimits for SimpleDVT factory to EasyTrack", add_evmscript_factory( factory=NEW_TARGET_LIMIT_FACTORY, permissions=( @@ -318,7 +317,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # # CSM ( - "20. Add staking module", + "20. Add Community Staking Module to Staking Router", agent_forward( [ ( @@ -338,7 +337,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "21. Grant request burn role to CSAccounting contract", + "21. Grant request burn role to CSAccounting", agent_forward( [ encode_oz_grant_role( @@ -350,7 +349,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "22. Grant resume role to agent", + "22. Grant resume role to Aragon Agent", agent_forward( [ encode_oz_grant_role( @@ -362,11 +361,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "23. Resume staking module", + "23. Resume Community Staking Module", agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), ), ( - "24. Revoke resume role from agent", + "24. Revoke resume role from Aragon Agent", agent_forward( [ encode_oz_revoke_role( @@ -378,7 +377,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "25. Update initial epoch", + "25. Update initial epoch on CSHashConsensus", agent_forward( [ ( @@ -389,7 +388,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "26. Add CS settle EL stealing factory to ET", + "26. Add CSMSettleElStealingPenalty factory to EasyTrack", add_evmscript_factory( factory=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), From 79515e1ca72dbd25683877302f75265fe9d484a4 Mon Sep 17 00:00:00 2001 From: maksim Date: Sun, 6 Oct 2024 17:10:38 +0200 Subject: [PATCH 136/220] test: fix accounting tests Add CSM module to accounting tests --- tests/regression/test_accounting.py | 295 +++++++++++++--------------- 1 file changed, 137 insertions(+), 158 deletions(-) diff --git a/tests/regression/test_accounting.py b/tests/regression/test_accounting.py index 81c8c3b14..a94679ddf 100644 --- a/tests/regression/test_accounting.py +++ b/tests/regression/test_accounting.py @@ -6,12 +6,25 @@ from utils.evm_script import encode_error from tests.conftest import Helpers from utils.config import contracts +from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.helpers import ETH, GWEI, ZERO_ADDRESS, almostEqWithDiff, eth_balance from utils.test.oracle_report_helpers import ONE_DAY, SHARE_RATE_PRECISION, oracle_report +from utils.test.csm_helpers import csm_add_node_operator, get_ea_member +from utils.config import ( + AGENT, + BURNER, + CSM_ADDRESS, + CS_FEE_DISTRIBUTOR_ADDRESS, + SIMPLE_DVT, + NODE_OPERATORS_REGISTRY +) + +from typing import TypedDict LIMITER_PRECISION_BASE = 10**9 MAX_BASIS_POINTS = 10_000 +pytestmark = pytest.mark.usefixtures("autoexecute_vote_ms") @pytest.fixture(scope="module") def accounting_oracle() -> Contract: @@ -148,9 +161,11 @@ def test_accounting_negative_cl_rebase(accounting_oracle: Contract, lido: Contra ), "PostTotalShares: TotalPooledEther differs from expected" -def test_accounting_cl_rebase_at_limits(accounting_oracle: Contract, lido: Contract): +def test_accounting_cl_rebase_at_limits(accounting_oracle: Contract, lido: Contract, stranger): """Check Lido rebase after accounting report with positive CL rebase close to the limits""" + _fill_csm_module_if_empty() + block_before_report = chain.height annual_increase_limit = contracts.oracle_report_sanity_checker.getOracleReportLimits()[2] @@ -183,59 +198,11 @@ def test_accounting_cl_rebase_at_limits(accounting_oracle: Contract, lido: Contr + withdrawals_finalized["amountOfETHLocked"] ), "TotalPooledEther change mismatch" - shares_as_fees_list = [e["sharesValue"] for e in _get_events(tx, TransferShares)] - - minted_shares_sum = 0 - - if withdrawals_finalized["amountOfETHLocked"] == 0: # no withdrawals processed - assert len(shares_as_fees_list) == 3, "Expected transfer of shares to NodeOperatorsRegistry, sDVT and DAO" - # the staking modules ids starts from 1, so SDVT has id = 2 - simple_dvt_stats = contracts.staking_router.getStakingModule(2) - # simple_dvt_treasury_fee = sdvt_share / share_pct * treasury_pct - simple_dvt_treasury_fee = ( - shares_as_fees_list[1] - * 100_00 - // simple_dvt_stats["stakingModuleFee"] - * simple_dvt_stats["treasuryFee"] - // 100_00 - ) - assert almostEqWithDiff( - shares_as_fees_list[0] + simple_dvt_treasury_fee, - shares_as_fees_list[2], - 100, # the precision may degrade after the division - ), "Shares minted to DAO and NodeOperatorsRegistry mismatch" + transfer_shares = _parse_transfer_shares_events(tx) - minted_shares_sum = shares_as_fees_list[0] + shares_as_fees_list[1] + shares_as_fees_list[2] - else: - staking_modules_count = contracts.staking_router.getStakingModulesCount() - # transfer to Burner, Treasury and each staking module - assert ( - len(shares_as_fees_list) == 2 + staking_modules_count - ), "Expected transfer of shares to NodeOperatorsRegistry and DAO" - - # transfer recipients: - # 0 - burner - # 1 - staking_modules[0] : node operators registry - # 2 - staking_modules[1] : simple DVT - # 3 - treasury - - # the staking modules ids starts from 1, so SDVT has id = 2 - simple_dvt_stats = contracts.staking_router.getStakingModule(2) - # simple_dvt_treasury_fee = sdvt_share / share_pct * treasury_pct - simple_dvt_treasury_fee = ( - shares_as_fees_list[2] - * 100_00 - // simple_dvt_stats["stakingModuleFee"] - * simple_dvt_stats["treasuryFee"] - // 100_00 - ) - assert almostEqWithDiff( - shares_as_fees_list[1] + simple_dvt_treasury_fee, - shares_as_fees_list[-1], - 100, # the precision may degrade after the division - ), "Shares minted to DAO and NodeOperatorsRegistry mismatch" + minted_shares_sum = _sum_minted_shares(transfer_shares) - minted_shares_sum = shares_as_fees_list[1] + shares_as_fees_list[2] + shares_as_fees_list[3] + _assert_minted_shares_total_sum(transfer_shares) token_rebased_event = _first_event(tx, TokenRebased) assert token_rebased_event["sharesMintedAsFees"] == minted_shares_sum, "TokenRebased: sharesMintedAsFee mismatch" @@ -573,6 +540,8 @@ def test_accounting_withdrawals_at_limits( ): """Test rebase with normal withdrawals amount""" + _fill_csm_module_if_empty() + block_before_report = chain.height withdrawals = _rebase_limit_wei(block_identifier=block_before_report) @@ -608,59 +577,9 @@ def test_accounting_withdrawals_at_limits( + withdrawals_finalized["amountOfETHLocked"] ), "TotalPooledEther change mismatch" - shares_as_fees_list = [e["sharesValue"] for e in _get_events(tx, TransferShares)] - - minted_shares_sum = 0 - - if withdrawals_finalized["amountOfETHLocked"] == 0: # no withdrawals processed - assert len(shares_as_fees_list) == 3, "Expected transfer of shares to NodeOperatorsRegistry, sDVT and DAO" - # the staking modules ids starts from 1, so SDVT has id = 2 - simple_dvt_stats = contracts.staking_router.getStakingModule(2) - # simple_dvt_treasury_fee = sdvt_share / share_pct * treasury_pct - simple_dvt_treasury_fee = ( - shares_as_fees_list[1] - * 100_00 - // simple_dvt_stats["stakingModuleFee"] - * simple_dvt_stats["treasuryFee"] - // 100_00 - ) - assert almostEqWithDiff( - shares_as_fees_list[0] + simple_dvt_treasury_fee, - shares_as_fees_list[2], - 100, # the precision may degrade after the division - ), "Shares minted to DAO and NodeOperatorsRegistry mismatch" - - minted_shares_sum = shares_as_fees_list[0] + shares_as_fees_list[1] + shares_as_fees_list[2] - else: - staking_modules_count = contracts.staking_router.getStakingModulesCount() - # transfer to Burner, Treasury and each staking module - assert ( - len(shares_as_fees_list) == 2 + staking_modules_count - ), "Expected transfer of shares to NodeOperatorsRegistry and DAO" - - # transfer recipients: - # 0 - burner - # 1 - staking_modules[0] : node operators registry - # 2 - staking_modules[1] : simple DVT - # 3 - treasury - - # the staking modules ids starts from 1, so SDVT has id = 2 - simple_dvt_stats = contracts.staking_router.getStakingModule(2) - # simple_dvt_treasury_fee = sdvt_share / share_pct * treasury_pct - simple_dvt_treasury_fee = ( - shares_as_fees_list[2] - * 100_00 - // simple_dvt_stats["stakingModuleFee"] - * simple_dvt_stats["treasuryFee"] - // 100_00 - ) - assert almostEqWithDiff( - shares_as_fees_list[1] + simple_dvt_treasury_fee, - shares_as_fees_list[-1], - 100, # the precision may degrade after the division - ), "Shares minted to DAO and NodeOperatorsRegistry mismatch" - - minted_shares_sum = shares_as_fees_list[1] + shares_as_fees_list[2] + shares_as_fees_list[3] + transfer_shares = _parse_transfer_shares_events(tx) + minted_shares_sum = _sum_minted_shares(transfer_shares) + _assert_minted_shares_total_sum(transfer_shares) token_rebased_event = _first_event(tx, TokenRebased) assert token_rebased_event["sharesMintedAsFees"] == minted_shares_sum, "TokenRebased: sharesMintedAsFee mismatch" @@ -688,6 +607,8 @@ def test_accounting_withdrawals_above_limits( ): """Test rebase with excess withdrawals amount""" + _fill_csm_module_if_empty() + block_before_report = chain.height expected_withdrawals = _rebase_limit_wei(block_identifier=block_before_report) @@ -725,59 +646,9 @@ def test_accounting_withdrawals_above_limits( + withdrawals_finalized["amountOfETHLocked"] ), "TotalPooledEther change mismatch" - shares_as_fees_list = [e["sharesValue"] for e in _get_events(tx, TransferShares)] - - minted_shares_sum = 0 - - if withdrawals_finalized["amountOfETHLocked"] == 0: # no withdrawals processed - assert len(shares_as_fees_list) == 3, "Expected transfer of shares to NodeOperatorsRegistry, sDVT and DAO" - # the staking modules ids starts from 1, so SDVT has id = 2 - simple_dvt_stats = contracts.staking_router.getStakingModule(2) - # simple_dvt_treasury_fee = sdvt_share / share_pct * treasury_pct - simple_dvt_treasury_fee = ( - shares_as_fees_list[1] - * 100_00 - // simple_dvt_stats["stakingModuleFee"] - * simple_dvt_stats["treasuryFee"] - // 100_00 - ) - assert almostEqWithDiff( - shares_as_fees_list[0] + simple_dvt_treasury_fee, - shares_as_fees_list[2], - 100, # the precision may degrade after the division - ), "Shares minted to DAO and NodeOperatorsRegistry mismatch" - - minted_shares_sum = shares_as_fees_list[0] + shares_as_fees_list[1] + shares_as_fees_list[2] - else: - staking_modules_count = contracts.staking_router.getStakingModulesCount() - # transfer to Burner, Treasury and each staking module - assert ( - len(shares_as_fees_list) == 2 + staking_modules_count - ), "Expected transfer of shares to NodeOperatorsRegistry and DAO" - - # transfer recipients: - # 0 - burner - # 1 - staking_modules[0] : node operators registry - # 2 - staking_modules[1] : simple DVT - # 3 - treasury - - # the staking modules ids starts from 1, so SDVT has id = 2 - simple_dvt_stats = contracts.staking_router.getStakingModule(2) - # simple_dvt_treasury_fee = sdvt_share / share_pct * treasury_pct - simple_dvt_treasury_fee = ( - shares_as_fees_list[2] - * 100_00 - // simple_dvt_stats["stakingModuleFee"] - * simple_dvt_stats["treasuryFee"] - // 100_00 - ) - assert almostEqWithDiff( - shares_as_fees_list[1] + simple_dvt_treasury_fee, - shares_as_fees_list[-1], - 100, # the precision may degrade after the division - ), "Shares minted to DAO and NodeOperatorsRegistry mismatch" - - minted_shares_sum = shares_as_fees_list[1] + shares_as_fees_list[2] + shares_as_fees_list[3] + transfer_shares = _parse_transfer_shares_events(tx) + minted_shares_sum = _sum_minted_shares(transfer_shares) + _assert_minted_shares_total_sum(transfer_shares) token_rebased_event = _first_event(tx, TokenRebased) assert token_rebased_event["sharesMintedAsFees"] == minted_shares_sum, "TokenRebased: sharesMintedAsFee mismatch" @@ -1139,3 +1010,111 @@ def _try_get_shares_burnt(tx: Any) -> SharesBurnt: return _first_event(tx, SharesBurnt) else: return SharesBurnt(account=ZERO_ADDRESS, preRebaseTokenAmount=0, postRebaseTokenAmount=0, sharesAmount=0) + +class TransferSharesResult(TypedDict): + burner: int + node_operators_registry: int + simple_dvt: int + csm: int + treasury: int + + +def _assert_minted_shares_total_sum (transfer_shares: TransferSharesResult): + # the staking modules ids starts from 1, so SDVT has id = 2 + simple_dvt_stats = contracts.staking_router.getStakingModule(2) + # simple_dvt_treasury_fee = sdvt_share / share_pct * treasury_pct + simple_dvt_treasury_fee = ( + transfer_shares["simple_dvt"] + * 100_00 + // simple_dvt_stats["stakingModuleFee"] + * simple_dvt_stats["treasuryFee"] + // 100_00 + ) + + csm_stats = contracts.staking_router.getStakingModule(3) + + csm_treasury_fee = ( + transfer_shares["csm"] + * 100_00 + // csm_stats["stakingModuleFee"] + * csm_stats["treasuryFee"] + // 100_00 + ) + + assert almostEqWithDiff( + transfer_shares["node_operators_registry"] + simple_dvt_treasury_fee + csm_treasury_fee, + transfer_shares["treasury"], + 100, # the precision may degrade after the division + ), "Shares minted to DAO and NodeOperatorsRegistry mismatch" + + +def _sum_minted_shares(transfer_shares: TransferSharesResult): + return transfer_shares["node_operators_registry"] + transfer_shares["simple_dvt"] + transfer_shares["csm"] + transfer_shares["treasury"] + + +def _parse_single_transfer_shares_event(transferShares: TransferShares, event_to: str): + print("_parse_single_transfer_shares_event") + assert transferShares["to"] == event_to, "Unexpected recipient" + return transferShares["sharesValue"] + +def _parse_transfer_shares_events(tx: Any): + has_withdrawals = _try_get_withdrawals_finalized(tx)["amountOfETHLocked"] > 0 + + staking_modules_count = contracts.staking_router.getStakingModulesCount() + assert staking_modules_count == 3, "Unexpected modules count" + + # transfer recipients: + # 0 - burner (if withdrawals > 0) + # 1 - staking_modules[0] : node operators registry + # 2 - staking_modules[1] : simple DVT + # 3 - staking_modules[2] : CSM + # 4 - treasury + # 5 - CSM module internal transfer to fee distributor contract + transfer_shares_events = _get_events(tx, TransferShares) + + assert (len(transfer_shares_events) == 6 if has_withdrawals else 5), "Invalid shares events count" + + result: TransferSharesResult = { + "burner": 0, + "node_operators_registry": 0, + "simple_dvt": 0, + "csm": 0, + "treasury": 0, + } + + assert (transfer_shares_events[-1]["from"] == CSM_ADDRESS and transfer_shares_events[-1]["to"] == CS_FEE_DISTRIBUTOR_ADDRESS),"Not a CSM internal transfer" + + result["treasury"] = _parse_single_transfer_shares_event(transfer_shares_events[-2], AGENT) + result["csm"] = _parse_single_transfer_shares_event(transfer_shares_events[-3], CSM_ADDRESS) + result["simple_dvt"] = _parse_single_transfer_shares_event(transfer_shares_events[-4], SIMPLE_DVT) + result["node_operators_registry"] = _parse_single_transfer_shares_event(transfer_shares_events[-5], NODE_OPERATORS_REGISTRY) + + if has_withdrawals: + assert transfer_shares_events[0]["to"] == BURNER, "First transfer event should be to burner" + result["burner"] = _parse_single_transfer_shares_event(transfer_shares_events[0], BURNER) + + return result + + +def _fill_csm_module_if_empty(): + # The tests which require this check were originally designed for running only with + # pre-defined modules configuration in mainnet + + # 1 - staking_modules[0] : node operators registry + # 2 - staking_modules[1] : simple DVT + # 3 - staking_modules[2] : csm + staking_modules = contracts.staking_router.getAllStakingModuleDigests() + assert len(staking_modules) == 3, "Modules count mismatch" + + def operators_count(digest): + return digest[0] + + assert operators_count(staking_modules[0]) > 0, "NOR module empty" + assert operators_count(staking_modules[1]) > 0, "Simple DVT module empty" + + if operators_count(staking_modules[2]) == 0: + keys_count = 5 + address, proof = get_ea_member() + csm_add_node_operator(contracts.csm, contracts.cs_accounting, address, proof, keys_count) + fill_deposit_buffer(keys_count) + contracts.lido.deposit(keys_count, 3, "0x", {"from": contracts.deposit_security_module}) From 682bfb4ef1cbaf4e7418251aac6bac1f97433c82 Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 9 Oct 2024 12:40:04 +0200 Subject: [PATCH 137/220] test: check burn shares permission for csm accounting contract --- tests/regression/test_permissions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/regression/test_permissions.py b/tests/regression/test_permissions.py index d288b9840..45caae860 100644 --- a/tests/regression/test_permissions.py +++ b/tests/regression/test_permissions.py @@ -62,7 +62,7 @@ def protocol_permissions(): "roles": { "DEFAULT_ADMIN_ROLE": [contracts.agent], "REQUEST_BURN_MY_STETH_ROLE": [contracts.agent], - "REQUEST_BURN_SHARES_ROLE": [contracts.lido, contracts.node_operators_registry, contracts.simple_dvt], + "REQUEST_BURN_SHARES_ROLE": [contracts.lido, contracts.node_operators_registry, contracts.simple_dvt, contracts.csm.accounting()], }, }, STAKING_ROUTER: { From 910d3aa5f30cb4c2ea06a64b9d1aa1cef630ca4d Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 9 Oct 2024 13:57:55 +0200 Subject: [PATCH 138/220] vote: update share thresholds --- configs/config_mainnet.py | 4 ++-- scripts/vote_sr_v2.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 7f93f0763..fb2623eb9 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -161,7 +161,7 @@ "0x637572617465642d6f6e636861696e2d76310000000000000000000000000000" ) SIMPLE_DVT_VERSION = 3 -SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 400 +SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 444 SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK = 150 SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE = 25 @@ -331,7 +331,7 @@ CS_MODULE_MODULE_FEE_BP = 600 CS_MODULE_TREASURY_FEE_BP = 400 CS_MODULE_TARGET_SHARE_BP = 100 -CS_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 100 +CS_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD = 125 CS_MODULE_MAX_DEPOSITS_PER_BLOCK = 30 CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE = 25 diff --git a/scripts/vote_sr_v2.py b/scripts/vote_sr_v2.py index 3da7cf04e..29476c109 100644 --- a/scripts/vote_sr_v2.py +++ b/scripts/vote_sr_v2.py @@ -90,7 +90,7 @@ ## SDVT module sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" -SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 400 +SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 444 SDVT_MAX_DEPOSITS_PER_BLOCK = 150 SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 SDVT_VERSION_REPO = ["2", "0", "0"] @@ -113,7 +113,7 @@ ## Parameters CS_MODULE_NAME = "Community Staking" CS_STAKE_SHARE_LIMIT = 100 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 100 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 125 CS_STAKING_MODULE_FEE = 600 CS_TREASURY_FEE = 400 CS_MAX_DEPOSITS_PER_BLOCK = 30 From b044b1ec77c5383ba5e8ce97b0f8dbf89e38bee5 Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 9 Oct 2024 14:25:30 +0200 Subject: [PATCH 139/220] vote: update easy track target limit factory address --- configs/config_mainnet.py | 2 +- scripts/vote_sr_v2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index fb2623eb9..694ecc91d 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -66,7 +66,7 @@ EASYTRACK_SIMPLE_DVT_SET_VETTED_VALIDATORS_LIMITS_FACTORY = "0xD75778b855886Fc5e1eA7D6bFADA9EB68b35C19D" EASYTRACK_SIMPLE_DVT_SET_NODE_OPERATOR_NAMES_FACTORY = "0x7d509BFF310d9460b1F613e4e40d342201a83Ae4" EASYTRACK_SIMPLE_DVT_SET_NODE_OPERATOR_REWARD_ADDRESSES_FACTORY = "0x589e298964b9181D9938B84bB034C3BB9024E2C0" -EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" +EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY = "0x161a4552A625844c822954C5AcBac928ee0f399B" EASYTRACK_SIMPLE_DVT_CHANGE_NODE_OPERATOR_MANAGERS_FACTORY = "0xE31A0599A6772BCf9b2bFc9e25cf941e793c9a7D" # Multisigs diff --git a/scripts/vote_sr_v2.py b/scripts/vote_sr_v2.py index 29476c109..80ffa9aaf 100644 --- a/scripts/vote_sr_v2.py +++ b/scripts/vote_sr_v2.py @@ -76,7 +76,7 @@ ## Easy track OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" # !!!! that is locally deployed factory address, before run set contract address here -NEW_TARGET_LIMIT_FACTORY = "0x8a6E9a8E0bB561f8cdAb1619ECc4585aaF126D73" +NEW_TARGET_LIMIT_FACTORY = "0x161a4552A625844c822954C5AcBac928ee0f399B" ## Curated module nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" From 8629b59e164939f400ceeb54e024c03e0d7a8e22 Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 9 Oct 2024 14:49:33 +0200 Subject: [PATCH 140/220] vote: sr-v2 vote update contract addresses --- configs/config_mainnet.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 694ecc91d..d63d81695 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -98,7 +98,7 @@ # LidoLocator LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0x3ABc4764f0237923d52056CFba7E9AEBf87113D3" # set address here after SR V2 deploy # Other upgrade addresses LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" @@ -123,7 +123,7 @@ ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" # NodeOperatorsRegistry aka Curated Staking Module -NODE_OPERATORS_REGISTRY_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" # set address here after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" # set address here after SR V2 deploy ## see NodeOperatorsRegistry's proxy appId() NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" NODE_OPERATORS_REGISTRY_VERSION = 3 @@ -145,7 +145,7 @@ CURATED_STAKING_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE = 25 # NodeOperatorsRegistry clone aka SimpleDVT -SIMPLE_DVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" +SIMPLE_DVT_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" ## see SimpleDVT's proxy appId() SIMPLE_DVT_ARAGON_APP_NAME = "simple-dvt" @@ -178,7 +178,7 @@ FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT = 1350 # 6 days # OracleReportSanityChecker -ORACLE_REPORT_SANITY_CHECKER = "0x9305c1Dbfe22c12c66339184C0025d7006f0f1cC" +ORACLE_REPORT_SANITY_CHECKER = "0x6232397ebac4f5772e53285B26c47914E9461E75" APPEARED_VALIDATORS_PER_DAY_LIMIT = 43200 EXITED_VALIDATORS_PER_DAY_LIMIT = 9000 ANNUAL_BALANCE_INCREASE_BP_LIMIT = 1000 # 10% @@ -198,7 +198,7 @@ TOTAL_COVER_SHARES_BURNT = 0 # DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # set address here after SR V2 deploy +DEPOSIT_SECURITY_MODULE = "0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD" # set address here after SR V2 deploy DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact DSM_MAX_OPERATORS_PER_UNVETTING = 200 DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS = 6646 @@ -216,7 +216,7 @@ # AccountingOracle # and its corresponding HashConsensus ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0x0e65898527E77210fB0133D00dd4C0E86Dc29bC7" # set address here after SR V2 deploy HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 @@ -265,7 +265,7 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" -STAKING_ROUTER_IMPL = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" # set address here after SR V2 deploy +STAKING_ROUTER_IMPL = "0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA" # set address here after SR V2 deploy STAKING_ROUTER_VERSION = 2 # do we need set this value now ? From f520840dcdc3bd43fd112d9378a7e2fc27bd7a0a Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 9 Oct 2024 16:48:30 +0200 Subject: [PATCH 141/220] test: fix csm oracle report frame --- configs/config_mainnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index d63d81695..8c9358232 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -325,7 +325,7 @@ SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" #CSM -CS_ORACLE_EPOCHS_PER_FRAME = 225 * 7 # 7 days +CS_ORACLE_EPOCHS_PER_FRAME = 225 * 28 # 28 days CS_MODULE_ID = 3 CS_MODULE_NAME = "Community Staking" CS_MODULE_MODULE_FEE_BP = 600 From 402f8357d7ef3902bda75cac9020dd30fa0bcc08 Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 9 Oct 2024 17:22:25 +0200 Subject: [PATCH 142/220] test: update oracle error upper limit --- configs/config_mainnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 8c9358232..2fc9b1cfc 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -190,7 +190,7 @@ MAX_POSITIVE_TOKEN_REBASE = 750000 INITIAL_SLASHING_AMOUNT_PWEI = 1000 INACTIVITY_PENALTIES_AMOUNT_PWEI = 101 -CL_BALANCE_ORACLES_ERROR_UPPER_BP_LIMIT = 74 +CL_BALANCE_ORACLES_ERROR_UPPER_BP_LIMIT = 50 # Burner BURNER = "0xD15a672319Cf0352560eE76d9e89eAB0889046D3" From 78fe7aa171de5319dfdf205dfec0ceb1635ac6db Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 9 Oct 2024 17:41:54 +0200 Subject: [PATCH 143/220] vote: rename vote file --- scripts/{vote_sr_v2.py => upgrade_sr_v2.py} | 0 tests/{test_vote_sr_v2.py => test_upgrade_sr_v2.py} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename scripts/{vote_sr_v2.py => upgrade_sr_v2.py} (100%) rename tests/{test_vote_sr_v2.py => test_upgrade_sr_v2.py} (99%) diff --git a/scripts/vote_sr_v2.py b/scripts/upgrade_sr_v2.py similarity index 100% rename from scripts/vote_sr_v2.py rename to scripts/upgrade_sr_v2.py diff --git a/tests/test_vote_sr_v2.py b/tests/test_upgrade_sr_v2.py similarity index 99% rename from tests/test_vote_sr_v2.py rename to tests/test_upgrade_sr_v2.py index 42b80b184..c5b5c3bd4 100644 --- a/tests/test_vote_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -14,7 +14,7 @@ CS_ACCOUNTING_ADDRESS, CSM_ADDRESS, ) -from scripts.vote_sr_v2 import ( +from scripts.upgrade_sr_v2 import ( start_vote, # oracles AO_CONSENSUS_VERSION, From 0c75b6baac6e92454b07bb8355d221327a8fdb16 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Thu, 10 Oct 2024 10:56:25 +0500 Subject: [PATCH 144/220] fix stale proof update roles tests --- configs/config_mainnet.py | 15 +++++----- tests/acceptance/test_csm.py | 53 +++++++++++++++++++++++++++++++++++- utils/test/csm_helpers.py | 31 +++++++++++---------- 3 files changed, 76 insertions(+), 23 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 2fc9b1cfc..b45c70a5a 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -336,12 +336,13 @@ CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE = 25 # ToDo: update after deploy -CSM_ADDRESS = "0xbc8eCccb89650c3E796e803CB009BF9b898CB359" -CS_ACCOUNTING_ADDRESS = "0x4B0FccF53589c1F185B35db88bB315a0bBF9a3e0" -CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xD537bF4b795b7D07Bd5F4bAf7017e3ce8360B1DE" -CS_EARLY_ADOPTION_ADDRESS = "0x1aa96efd2B002541E830CB7f60e473AA24e31F9A" -CS_FEE_DISTRIBUTOR_ADDRESS = "0x5847798CE8c89e3Fff59AE5fA30BEC0d406b5687" -CS_FEE_ORACLE_ADDRESS = "0x4e3E7dC9D84dA7BE8f017f4C36153A61341736d4" +CSM_COMMITTEE_MS = "0xC52fC3081123073078698F1EAc2f1Dc7Bd71880f" +CSM_ADDRESS = "0xc830Ad2FDfCC2f368fE5DeC93b1Dc72ecABb3691" +CS_ACCOUNTING_ADDRESS = "0x741e3E1f81041c62C2A97d0b6E567AcaB09A6232" +CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xC6D563d5c2243b27e7294511063f563ED701EA2C" +CS_EARLY_ADOPTION_ADDRESS = "0x8BE16B874F47371C42498b499837Ed87D7661E86" +CS_FEE_DISTRIBUTOR_ADDRESS = "0x0AC45e945A008D3fc19da8f591be8601C1F63130" +CS_FEE_ORACLE_ADDRESS = "0xFE0F4Cf81B5c0a6Fd65a610FD9488F33aE9095cB" CS_GATE_SEAL_ADDRESS = "0x5cFCa30450B1e5548F140C24A47E36c10CE306F0" -CS_VERIFIER_ADDRESS = "0x0C60536783db9ED5A2B216970B10FF2243d317dD" +CS_VERIFIER_ADDRESS = "0x5847798CE8c89e3Fff59AE5fA30BEC0d406b5687" diff --git a/tests/acceptance/test_csm.py b/tests/acceptance/test_csm.py index 357268c09..bd3b1a341 100644 --- a/tests/acceptance/test_csm.py +++ b/tests/acceptance/test_csm.py @@ -26,7 +26,8 @@ CHAIN_SLOTS_PER_EPOCH, CS_ORACLE_EPOCHS_PER_FRAME, ORACLE_QUORUM, - ORACLE_COMMITTEE + ORACLE_COMMITTEE, + CSM_COMMITTEE_MS ) contracts: ContractsLazyLoader = contracts @@ -89,10 +90,27 @@ def test_init_state(self, csm): def test_roles(self, csm): assert csm.hasRole(csm.STAKING_ROUTER_ROLE(), STAKING_ROUTER) + assert csm.getRoleMemberCount(csm.STAKING_ROUTER_ROLE()) == 1 + assert csm.hasRole(csm.DEFAULT_ADMIN_ROLE(), AGENT) + assert csm.getRoleMemberCount(csm.DEFAULT_ADMIN_ROLE()) == 1 + assert csm.hasRole(csm.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) + assert csm.getRoleMemberCount(csm.PAUSE_ROLE()) == 1 + + assert csm.hasRole(csm.REPORT_EL_REWARDS_STEALING_PENALTY_ROLE(), CSM_COMMITTEE_MS) + assert csm.getRoleMemberCount(csm.REPORT_EL_REWARDS_STEALING_PENALTY_ROLE()) == 1 + assert csm.hasRole(csm.SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE(), EASYTRACK_EVMSCRIPT_EXECUTOR) + assert csm.getRoleMemberCount(csm.SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE()) == 1 + assert csm.hasRole(csm.VERIFIER_ROLE(), CS_VERIFIER_ADDRESS) + assert csm.getRoleMemberCount(csm.VERIFIER_ROLE()) == 1 + + assert csm.getRoleMemberCount(csm.RESUME_ROLE()) == 0 + assert csm.getRoleMemberCount(csm.MODULE_MANAGER_ROLE()) == 0 + assert csm.getRoleMemberCount(csm.RECOVERER_ROLE()) == 0 + class TestAccounting: def test_initial_state(self, accounting): @@ -107,9 +125,24 @@ def test_initial_state(self, accounting): def test_roles(self, accounting): assert accounting.hasRole(accounting.SET_BOND_CURVE_ROLE(), CSM_ADDRESS) + assert accounting.hasRole(accounting.SET_BOND_CURVE_ROLE(), CSM_COMMITTEE_MS) + assert accounting.getRoleMemberCount(accounting.SET_BOND_CURVE_ROLE()) == 2 + assert accounting.hasRole(accounting.RESET_BOND_CURVE_ROLE(), CSM_ADDRESS) + assert accounting.hasRole(accounting.RESET_BOND_CURVE_ROLE(), CSM_COMMITTEE_MS) + assert accounting.getRoleMemberCount(accounting.RESET_BOND_CURVE_ROLE()) == 2 + assert accounting.hasRole(accounting.DEFAULT_ADMIN_ROLE(), AGENT) + assert accounting.getRoleMemberCount(accounting.DEFAULT_ADMIN_ROLE()) == 1 + assert accounting.hasRole(accounting.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) + assert accounting.getRoleMemberCount(accounting.PAUSE_ROLE()) == 1 + + assert accounting.getRoleMemberCount(accounting.RESUME_ROLE()) == 0 + assert accounting.getRoleMemberCount(accounting.ACCOUNTING_MANAGER_ROLE()) == 0 + assert accounting.getRoleMemberCount(accounting.MANAGE_BOND_CURVES_ROLE()) == 0 + assert accounting.getRoleMemberCount(accounting.RECOVERER_ROLE()) == 0 + def test_allowances(self, lido): uin256_max = 2 ** 256 - 1 @@ -130,6 +163,9 @@ def test_initial_state(self, fee_distributor): def test_roles(self, fee_distributor): assert fee_distributor.hasRole(fee_distributor.DEFAULT_ADMIN_ROLE(), AGENT) + assert fee_distributor.getRoleMemberCount(fee_distributor.DEFAULT_ADMIN_ROLE()) == 1 + + assert fee_distributor.getRoleMemberCount(fee_distributor.RECOVERER_ROLE()) == 0 class TestFeeOracle: @@ -154,7 +190,15 @@ def test_initial_state(self, fee_oracle): def test_roles(self, fee_oracle): assert fee_oracle.hasRole(fee_oracle.DEFAULT_ADMIN_ROLE(), AGENT) + assert fee_oracle.getRoleMemberCount(fee_oracle.DEFAULT_ADMIN_ROLE()) == 1 + assert fee_oracle.hasRole(fee_oracle.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) + assert fee_oracle.getRoleMemberCount(fee_oracle.PAUSE_ROLE()) == 1 + + assert fee_oracle.getRoleMemberCount(fee_oracle.CONTRACT_MANAGER_ROLE()) == 0 + assert fee_oracle.getRoleMemberCount(fee_oracle.SUBMIT_DATA_ROLE()) == 0 + assert fee_oracle.getRoleMemberCount(fee_oracle.RESUME_ROLE()) == 0 + assert fee_oracle.getRoleMemberCount(fee_oracle.RECOVERER_ROLE()) == 0 class TestHashConsensus: @@ -187,6 +231,13 @@ def test_initial_state(self, hash_consensus): def test_roles(self, hash_consensus): assert hash_consensus.hasRole(hash_consensus.DEFAULT_ADMIN_ROLE(), AGENT) + assert hash_consensus.getRoleMemberCount(hash_consensus.DEFAULT_ADMIN_ROLE()) == 1 + + assert hash_consensus.getRoleMemberCount(hash_consensus.MANAGE_MEMBERS_AND_QUORUM_ROLE()) == 0 + assert hash_consensus.getRoleMemberCount(hash_consensus.DISABLE_CONSENSUS_ROLE()) == 0 + assert hash_consensus.getRoleMemberCount(hash_consensus.MANAGE_FRAME_CONFIG_ROLE()) == 0 + assert hash_consensus.getRoleMemberCount(hash_consensus.MANAGE_FAST_LANE_CONFIG_ROLE()) == 0 + assert hash_consensus.getRoleMemberCount(hash_consensus.MANAGE_REPORT_PROCESSOR_ROLE()) == 0 def test_early_adoption_state(early_adoption): assert early_adoption.MODULE() == CSM_ADDRESS diff --git a/utils/test/csm_helpers.py b/utils/test/csm_helpers.py index 8df52baab..7924973f9 100644 --- a/utils/test/csm_helpers.py +++ b/utils/test/csm_helpers.py @@ -10,21 +10,22 @@ def get_ea_member(): Random address and proof for EA member """ address = "0x00200f4e638e81ebe172daa18c9193a33a50bbbd" - proof = ["0x6afb48863bdb84141ef424715c70cd61e5d629a293038b2e55b2aaa330955435", - "0xf2cbc3e761642defc881539fb26fd2f349c87ac9baa031572693d4b47286d521", - "0x526c3d791066e220842b26d606a332cc22d088eb0d1431c43d6c5a8503417f4e", - "0x25f371f22e592b9541b1fe8c3e2a599b3db0b11e9b027bffe525dc48b6971bf5", - "0xffaad8403c4681c00ce2a7d6c82f2f4343ec7ef0efd9dd1959e37a55c71949bc", - "0xf86d0c08277b41ad7d4b9640be4c1e6b0e2eed1fd4bfc084c300086cb638b933", - "0x3c66b0db484c5bd7351114a5e7fb073604fd8772254ad3ef02432918a7b65f2c", - "0x47d2ab6d81d882809ffb9df212c126fbbb5fe01c0849cb42d8101fe0f5b5ea1c", - "0x62373951ea824814af660ae6276d03fec5e734f9ea8e9fe662e600b19fd58dea", - "0x812242ec081e8ebf25e682ff968a40dbf0786caa89ba18958d7f91f7e981e415", - "0x1b3e4aade81953dbfc7df20d22852a95c255bf0bcf5f186115f9f439b29f4845", - "0x2db100e320128d95cf46a003497bc5dcf25cdc62a1e66a89f0fa7c79b1a858ad", - "0x03d33582f7cac74515d95d4ab3711d95ce9814df7351a1a46223d3bb4c3fdd44", - "0x566d2db5a4091a4c3152e2e3ba7a26d44b9f09515d4d8e587cf7f8aea77e38f0", - "0xd415d9673b0b81ccf04e5ed1317f6a2ec5c94bc3c8d14e5d302225ad9b99b137"] + proof = [ + "0x6afd64d1f8e5feed98652d45b758fcbff17eea77665d51f0e531d692a5054756", + "0x52e265b49b47b47690ed87febf862cd32a651b9ab187cad973bc9b77749bb219", + "0x35e699543254ce0682e153798e663901c7b14a637c6823def95687ce98c3bfd2", + "0x90c4d893c062e47126e1fb88c62d7f1addb6787d7681c8b4783e77848fd94ce3", + "0xcc571b6d9faf0a49b61d00cb56d518a9ac9bc61b9ef63c7b6376a3ead99bd455", + "0x190eb8e475726914932a14a9f62b854636a9dcb6323c4d97ac6630fcd29dc33c", + "0x4ac93583eb5d1fb5546b438eac0a489b07b0d62910c4bab3e7b41f0042831d48", + "0xcdc54828056fbe5307ece8e4138766177cd9568ffd68564b37d3deaaf112bb6c", + "0x4d63ec7d0dcc7a38ac4984b6ea8fad8255dfd6419c6c66684e49676d3112e062", + "0x5c39f6b822174cc0267fa29cb2c74340b837859bbc95beca29997689334b4895", + "0x2980e52feb24b69169c73a9618107b58ae5bea120649a045aba137b07e822172", + "0xdbaa84b6f34f08ec11a23797a3497898e75dec4e99bf42d63e7cbfee0dee67d6", + "0xc4556dc19f0330ccc6c929b09a965e05c360d32a5c71c3f64b4123fda973b8dd", + "0x617a04e701d0b1c8e0e96c278ba4caf00e2d787e4287e52fcc4b5f248d89c2b3" + ] return address, proof From 035bb8c5fda0dcffd64f38612f098f5050bab0d1 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Fri, 11 Oct 2024 11:59:19 +0500 Subject: [PATCH 145/220] mainnet addresses --- configs/config_mainnet.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index b45c70a5a..fd3a41c3c 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -337,12 +337,12 @@ # ToDo: update after deploy CSM_COMMITTEE_MS = "0xC52fC3081123073078698F1EAc2f1Dc7Bd71880f" -CSM_ADDRESS = "0xc830Ad2FDfCC2f368fE5DeC93b1Dc72ecABb3691" -CS_ACCOUNTING_ADDRESS = "0x741e3E1f81041c62C2A97d0b6E567AcaB09A6232" -CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0xC6D563d5c2243b27e7294511063f563ED701EA2C" -CS_EARLY_ADOPTION_ADDRESS = "0x8BE16B874F47371C42498b499837Ed87D7661E86" -CS_FEE_DISTRIBUTOR_ADDRESS = "0x0AC45e945A008D3fc19da8f591be8601C1F63130" -CS_FEE_ORACLE_ADDRESS = "0xFE0F4Cf81B5c0a6Fd65a610FD9488F33aE9095cB" +CSM_ADDRESS = "0xdA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F" +CS_ACCOUNTING_ADDRESS = "0x4d72BFF1BeaC69925F8Bd12526a39BAAb069e5Da" +CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0x71093efF8D8599b5fA340D665Ad60fA7C80688e4" +CS_EARLY_ADOPTION_ADDRESS = "0x3D5148ad93e2ae5DedD1f7A8B3C19E7F67F90c0E" +CS_FEE_DISTRIBUTOR_ADDRESS = "0xD99CC66fEC647E68294C6477B40fC7E0F6F618D0" +CS_FEE_ORACLE_ADDRESS = "0x4D4074628678Bd302921c20573EEa1ed38DdF7FB" CS_GATE_SEAL_ADDRESS = "0x5cFCa30450B1e5548F140C24A47E36c10CE306F0" -CS_VERIFIER_ADDRESS = "0x5847798CE8c89e3Fff59AE5fA30BEC0d406b5687" +CS_VERIFIER_ADDRESS = "0x3Dfc50f22aCA652a0a6F28a0F892ab62074b5583" From 246434fc70a68a51a889c583ad2dd78c76c01003 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Sat, 12 Oct 2024 12:44:15 +0400 Subject: [PATCH 146/220] fix: top up agent address with eth when run on fork --- utils/config.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utils/config.py b/utils/config.py index 0e8bc1e42..7f2ee4d4c 100644 --- a/utils/config.py +++ b/utils/config.py @@ -75,6 +75,11 @@ def local_deployer() -> LocalAccount: """ deployer = accounts[4] agent = accounts.at(AGENT, force=True) + + if web3.eth.get_balance(agent.address) < 10 ** 18: + from utils.balance import set_balance + set_balance(agent.address, 1) + interface.MiniMeToken(LDO_TOKEN).transfer(deployer, 10**18, {"from": agent}) return deployer From 679d8d18526554b1550769465470c4bfda763d84 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Sun, 13 Oct 2024 19:08:12 +0400 Subject: [PATCH 147/220] feat: add start_and_execute_vote_on_fork script for sr+csm upgrade --- scripts/upgrade_sr_v2.py | 14 ++++++++++++++ utils/mainnet_fork.py | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 80ffa9aaf..902dd08d9 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -70,6 +70,7 @@ from brownie.network.transaction import TransactionReceipt from utils.agent import agent_forward +from utils.mainnet_fork import pass_and_exec_dao_vote # SR @@ -419,3 +420,16 @@ def main(): vote_id >= 0 and print(f"Vote created: {vote_id}.") time.sleep(5) # hack for waiting thread #2. + + +def start_and_execute_vote_on_fork(): + if get_is_live(): + raise Exception("This script is for local testing only.") + + tx_params = {"from": get_deployer_account()} + vote_id, _ = start_vote(tx_params=tx_params, silent=True) + + time.sleep(5) # hack for waiting thread #2. + + print(f"Vote created: {vote_id}.") + pass_and_exec_dao_vote(int(vote_id)) diff --git a/utils/mainnet_fork.py b/utils/mainnet_fork.py index fe3a718ef..3c03ee6ac 100644 --- a/utils/mainnet_fork.py +++ b/utils/mainnet_fork.py @@ -36,7 +36,7 @@ def pass_and_exec_dao_vote(vote_id): for holder_addr in ldo_holders: print(f" voting from {holder_addr}") - helper_acct.transfer(holder_addr, "0.1 ether", silent=True) + helper_acct.transfer(holder_addr, "1 ether", silent=True) account = accounts.at(holder_addr, force=True) dao_voting.vote(vote_id, True, False, {"from": account, "silent": True}) From 8a45fc1060d7323249088f72ffa1156489b18da5 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Mon, 14 Oct 2024 11:22:45 +0400 Subject: [PATCH 148/220] fix: new locator implementation address --- tests/test_upgrade_sr_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index c5b5c3bd4..e90a8ad0a 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -62,7 +62,7 @@ from utils.easy_track import create_permissions, create_permissions_overloaded # Impl addresses before vote -OLD_LOCATOR_IMPL_ADDRESS = "0x1D920cc5bACf7eE506a271a5259f2417CaDeCE1d" +OLD_LOCATOR_IMPL_ADDRESS = "0x39aFE23cE59e8Ef196b81F0DCb165E9aD38b9463" OLD_SR_IMPL_ADDRESS = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" OLD_NOR_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" OLD_SDVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" From 6932a2dc003c93e2f7986f1aaf6b379dc2daa550 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 14 Oct 2024 13:11:16 +0400 Subject: [PATCH 149/220] fix: change address csm settle el rewards factory --- scripts/upgrade_sr_v2.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 902dd08d9..875ab0608 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -76,7 +76,6 @@ ## Easy track OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" -# !!!! that is locally deployed factory address, before run set contract address here NEW_TARGET_LIMIT_FACTORY = "0x161a4552A625844c822954C5AcBac928ee0f399B" ## Curated module @@ -108,8 +107,7 @@ # CSM ## Easy track -# !!!! that is locally deployed factory address, before run set contract address here -EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0x2963ff0196a901ec3F56d7531e7C4Ce8F226462B" +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" ## Parameters CS_MODULE_NAME = "Community Staking" @@ -119,10 +117,10 @@ CS_TREASURY_FEE = 400 CS_MAX_DEPOSITS_PER_BLOCK = 30 CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 58050 +CS_ORACLE_INITIAL_EPOCH = 58050 # TODO: need to check description = """ -Proposal to support DSM 2.0 and CSM Module +Proposal to support SR 2.0 and CSM Module """ From 6c6f07034729a078ae8dd70ad841abadd7d83b57 Mon Sep 17 00:00:00 2001 From: maksim Date: Mon, 14 Oct 2024 11:15:19 +0200 Subject: [PATCH 150/220] test: fix dsm snapshot --- tests/snapshot/test_dsm.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/snapshot/test_dsm.py b/tests/snapshot/test_dsm.py index a30c0f022..b4756c4e0 100644 --- a/tests/snapshot/test_dsm.py +++ b/tests/snapshot/test_dsm.py @@ -62,11 +62,6 @@ def test_dsm_no_changes_in_views_with_ops( { "pauseDeposits": pause_deposits, "setOwner": lambda dsm: dsm.setOwner(new_owner.address, {"from": dsm.getOwner()}), - "setMaxDeposits(42)": lambda dsm: dsm.setMaxDeposits(42, {"from": new_owner.address}), - "setMinDepositBlockDistance(17)": lambda dsm: dsm.setMinDepositBlockDistance( - 17, - {"from": new_owner.address}, - ), "removeGuardian(existing)": lambda dsm: dsm.removeGuardian( guardian.address, 3, @@ -102,6 +97,8 @@ def test_dsm_no_changes_in_views_with_ops( "setGuardianQuorum(0)": lambda dsm: dsm.setGuardianQuorum(0, {"from": new_owner.address}), "setGuardianQuorum(3)": lambda dsm: dsm.setGuardianQuorum(3, {"from": new_owner.address}), "unpauseDeposits": resume_deposits, + "setMaxOperatorsPerUnvetting(42)": lambda dsm: dsm.setMaxOperatorsPerUnvetting(42, {"from": new_owner.address}), + } ) _stacks_equal(stacks) @@ -110,7 +107,6 @@ def test_dsm_no_changes_in_views_with_ops( def pause_deposits(dsm: Contract): dsm.pauseDeposits( chain.height, - 1, # NOR [0, 0], # skip signature {"from": dsm.getGuardians()[0]}, ) @@ -118,7 +114,6 @@ def pause_deposits(dsm: Contract): def resume_deposits(dsm: Contract): dsm.unpauseDeposits( - 1, # NOR {"from": dsm.getOwner()}, ) @@ -136,7 +131,7 @@ def _snap(dsm): block = chain.height with brownie.multicall(block_identifier=block): return { - "block_number": chain.height, + # "block_number": chain.height, "chain_time": web3.eth.get_block(chain.height)["timestamp"], "DEPOSIT_CONTRACT": dsm.DEPOSIT_CONTRACT(), "LIDO": dsm.LIDO(), @@ -149,9 +144,10 @@ def _snap(dsm): "isGuardian(positive)": dsm.isGuardian(guardian.address), "isGuardian(negative)": dsm.isGuardian(accounts[0].address), "isGuardian(changes)": dsm.isGuardian(some_eoa.address), - "getMaxDeposits": dsm.getMaxDeposits(), - "getMinDepositBlockDistance": dsm.getMinDepositBlockDistance(), "getPauseIntentValidityPeriodBlocks": dsm.getPauseIntentValidityPeriodBlocks(), + "getMaxOperatorsPerUnvetting": dsm.getMaxOperatorsPerUnvetting(), + "getLastDepositBlock": dsm.getLastDepositBlock(), + "isDepositsPaused": dsm.isDepositsPaused(), # NOTE: unchecked views # Implementation address changes # "address": dsm.address, From 5b3ea6165e7120c69d13a9eb7a09de33ce5e0bda Mon Sep 17 00:00:00 2001 From: Dmitry Gusakov Date: Mon, 14 Oct 2024 11:50:04 +0200 Subject: [PATCH 151/220] fix: Remove redundant comments --- configs/config_mainnet.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index fd3a41c3c..f4dd0260a 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -68,6 +68,7 @@ EASYTRACK_SIMPLE_DVT_SET_NODE_OPERATOR_REWARD_ADDRESSES_FACTORY = "0x589e298964b9181D9938B84bB034C3BB9024E2C0" EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY = "0x161a4552A625844c822954C5AcBac928ee0f399B" EASYTRACK_SIMPLE_DVT_CHANGE_NODE_OPERATOR_MANAGERS_FACTORY = "0xE31A0599A6772BCf9b2bFc9e25cf941e793c9a7D" +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" # Multisigs FINANCE_MULTISIG = "0x48F300bD3C52c7dA6aAbDE4B683dEB27d38B9ABb" @@ -98,7 +99,7 @@ # LidoLocator LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -LIDO_LOCATOR_IMPL = "0x3ABc4764f0237923d52056CFba7E9AEBf87113D3" # set address here after SR V2 deploy +LIDO_LOCATOR_IMPL = "0x3abc4764f0237923d52056cfba7e9aebf87113d3" # Other upgrade addresses LIDO_V2_UPGRADE_TEMPLATE = "0xa818fF9EC93122Bf9401ab4340C42De638CD600a" @@ -123,7 +124,7 @@ ORACLE_ARAGON_APP_ID = "0x8b47ba2a8454ec799cd91646e7ec47168e91fd139b23f017455f3e5898aaba93" # NodeOperatorsRegistry aka Curated Staking Module -NODE_OPERATORS_REGISTRY_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" # set address here after SR V2 deploy +NODE_OPERATORS_REGISTRY_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" ## see NodeOperatorsRegistry's proxy appId() NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" NODE_OPERATORS_REGISTRY_VERSION = 3 @@ -198,7 +199,7 @@ TOTAL_COVER_SHARES_BURNT = 0 # DepositSecurityModule -DEPOSIT_SECURITY_MODULE = "0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD" # set address here after SR V2 deploy +DEPOSIT_SECURITY_MODULE = "0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD" DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" # dsm address before SR V2 enact DSM_MAX_OPERATORS_PER_UNVETTING = 200 DSM_PAUSE_INTENT_VALIDITY_PERIOD_BLOCKS = 6646 @@ -216,7 +217,7 @@ # AccountingOracle # and its corresponding HashConsensus ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -ACCOUNTING_ORACLE_IMPL = "0x0e65898527E77210fB0133D00dd4C0E86Dc29bC7" # set address here after SR V2 deploy +ACCOUNTING_ORACLE_IMPL = "0x0e65898527E77210fB0133D00dd4C0E86Dc29bC7" HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" AO_EPOCHS_PER_FRAME = 225 AO_FAST_LANE_LENGTH_SLOTS = 100 @@ -265,7 +266,7 @@ # StakingRouter STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" -STAKING_ROUTER_IMPL = "0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA" # set address here after SR V2 deploy +STAKING_ROUTER_IMPL = "0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA" STAKING_ROUTER_VERSION = 2 # do we need set this value now ? @@ -335,7 +336,6 @@ CS_MODULE_MAX_DEPOSITS_PER_BLOCK = 30 CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -# ToDo: update after deploy CSM_COMMITTEE_MS = "0xC52fC3081123073078698F1EAc2f1Dc7Bd71880f" CSM_ADDRESS = "0xdA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F" CS_ACCOUNTING_ADDRESS = "0x4d72BFF1BeaC69925F8Bd12526a39BAAb069e5Da" From e939890a16dcb801ac74262274dd7592b6892916 Mon Sep 17 00:00:00 2001 From: maksim Date: Mon, 14 Oct 2024 11:59:51 +0200 Subject: [PATCH 152/220] test: fix nor shapshot test --- .../snapshot/test_node_operators_registry.py | 93 ++++++++++++------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/tests/snapshot/test_node_operators_registry.py b/tests/snapshot/test_node_operators_registry.py index a990e203e..fb34462d8 100644 --- a/tests/snapshot/test_node_operators_registry.py +++ b/tests/snapshot/test_node_operators_registry.py @@ -7,7 +7,11 @@ from brownie.convert.datatypes import ReturnValue from tests.snapshot.utils import get_slot -from utils.config import contracts +from utils.config import ( + contracts, + DEPOSIT_SECURITY_MODULE, + DEPOSIT_SECURITY_MODULE_V2 +) from utils.mainnet_fork import chain_snapshot from utils.test.snapshot_helpers import dict_zip from utils.import_current_votes import is_there_any_vote_scripts, start_and_execute_votes @@ -42,6 +46,18 @@ def deposit_security_module_eoa(accounts, EtherFunder): return accounts.at(contracts.deposit_security_module, force=True) +@pytest.fixture(scope="module") +def old_deposit_security_module_eoa(accounts, EtherFunder): + EtherFunder.deploy(DEPOSIT_SECURITY_MODULE_V2, {"from": accounts[0], "amount": "10 ether"}) + return accounts.at(DEPOSIT_SECURITY_MODULE_V2, force=True) + + +@pytest.fixture(scope="module") +def new_deposit_security_module_eoa(accounts, EtherFunder): + EtherFunder.deploy(DEPOSIT_SECURITY_MODULE, {"from": accounts[0], "amount": "10 ether"}) + return accounts.at(DEPOSIT_SECURITY_MODULE, force=True) + + @pytest.fixture(scope="module") def voting_eoa(accounts): return accounts.at(contracts.voting.address, force=True) @@ -50,7 +66,8 @@ def voting_eoa(accounts): def test_node_operator_basic_flow( accounts, helpers, - deposit_security_module_eoa, + old_deposit_security_module_eoa, + new_deposit_security_module_eoa, voting_eoa, agent_eoa, vote_ids_from_env, @@ -70,38 +87,42 @@ def test_node_operator_basic_flow( "signature_batch": random_hexstr(10 * SIGNATURE_LENGTH), } - actions = { - "add_node_operator": lambda: contracts.node_operators_registry.addNodeOperator( - "new_node_operator", new_node_operator["reward_address"], {"from": voting_eoa} - ), - "add_signing_keys_operator_bh": lambda: contracts.node_operators_registry.addSigningKeysOperatorBH( - new_node_operator["id"], - new_node_operator["validators_count"], - new_node_operator["public_keys_batch"], - new_node_operator["signature_batch"], - {"from": new_node_operator["reward_address"]}, - ), - "set_staking_limit": lambda: contracts.node_operators_registry.setNodeOperatorStakingLimit( - new_node_operator["id"], new_node_operator["staking_limit"], {"from": voting_eoa} - ), - "submit": lambda: contracts.lido.submit(ZERO_ADDRESS, {"from": staker, "amount": submit_amount}), - "deposit": lambda: contracts.lido.deposit(deposits_count, 1, "0x", {"from": deposit_security_module_eoa}), - "remove_signing_keys": lambda: contracts.node_operators_registry.removeSigningKeys( - new_node_operator["id"], - new_node_operator["staking_limit"], - 1, - {"from": voting_eoa}, - ), - "deactivate_node_operator": lambda: contracts.node_operators_registry.deactivateNodeOperator( - new_node_operator["id"], {"from": voting_eoa} - ), - "withdrawal_credentials_change": lambda: contracts.staking_router.setWithdrawalCredentials( - "0xdeadbeef", {"from": voting_eoa} - ), - "activate_node_operator": lambda: contracts.node_operators_registry.activateNodeOperator( - new_node_operator["id"], {"from": voting_eoa} - ), - } + def create_actions(dsm_eoa): + actions = { + "add_node_operator": lambda: contracts.node_operators_registry.addNodeOperator( + "new_node_operator", new_node_operator["reward_address"], {"from": voting_eoa} + ), + "add_signing_keys_operator_bh": lambda: contracts.node_operators_registry.addSigningKeysOperatorBH( + new_node_operator["id"], + new_node_operator["validators_count"], + new_node_operator["public_keys_batch"], + new_node_operator["signature_batch"], + {"from": new_node_operator["reward_address"]}, + ), + "set_staking_limit": lambda: contracts.node_operators_registry.setNodeOperatorStakingLimit( + new_node_operator["id"], new_node_operator["staking_limit"], {"from": voting_eoa} + ), + "submit": lambda: contracts.lido.submit(ZERO_ADDRESS, {"from": staker, "amount": submit_amount}), + "deposit": lambda: contracts.lido.deposit(deposits_count, 1, "0x", {"from": dsm_eoa}), + "remove_signing_keys": lambda: contracts.node_operators_registry.removeSigningKeys( + new_node_operator["id"], + new_node_operator["staking_limit"], + 1, + {"from": voting_eoa}, + ), + "deactivate_node_operator": lambda: contracts.node_operators_registry.deactivateNodeOperator( + new_node_operator["id"], {"from": voting_eoa} + ), + "withdrawal_credentials_change": lambda: contracts.staking_router.setWithdrawalCredentials( + "0xdeadbeef", {"from": voting_eoa} + ), + "activate_node_operator": lambda: contracts.node_operators_registry.activateNodeOperator( + new_node_operator["id"], {"from": voting_eoa} + ), + } + + return actions + snapshot_before_update = {} snapshot_after_update = {} @@ -110,7 +131,7 @@ def test_node_operator_basic_flow( make_snapshot(contracts.node_operators_registry) with chain_snapshot(): - snapshot_before_update = run_scenario(actions=actions, snapshooter=make_snapshot) + snapshot_before_update = run_scenario(actions=create_actions(old_deposit_security_module_eoa), snapshooter=make_snapshot) with chain_snapshot(): @@ -118,7 +139,7 @@ def test_node_operator_basic_flow( helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") else: start_and_execute_votes(contracts.voting, helpers) - snapshot_after_update = run_scenario(actions=actions, snapshooter=make_snapshot) + snapshot_after_update = run_scenario(actions=create_actions(new_deposit_security_module_eoa), snapshooter=make_snapshot) assert snapshot_before_update.keys() == snapshot_after_update.keys() From 5601bf7c793a220969285636d99bd7707998a52d Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 14 Oct 2024 14:05:25 +0400 Subject: [PATCH 153/220] fix: expand description --- scripts/upgrade_sr_v2.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 875ab0608..e6bd5142e 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -121,6 +121,35 @@ description = """ Proposal to support SR 2.0 and CSM Module + +1. Update Locator implementation +2. Revoke pause role from old Deposit Security Module +3. Revoke resume role from old Deposit Security Module +4. Grant unvetting role to new Deposit Security Module +5. Update Staking Router implementation +6. Call finalize upgrade on Staking Router +7. Publish new Node Operators Registry implementation in Node Operators Registry app APM repo +8. Update Node Operators Registry implementation +9. Finalize Node Operators Registry upgrade +10. Publish new SimpleDVT implementation in SimpleDVT app APM repo +11. Update SimpleDVT implementation +12. Finalize SimpleDVT upgrade +13. Update Accounting Oracle implementation +14. Finalize Accounting Oracle upgrade and update consensus version +15. Grant manage consensus role to Aragon Agent +16. Update Validator Exit Bus Oracle consensus version +17. Revoke manage consensus role from Aragon Agent +18. Remove old UpdateTargetValidatorLimits for SimpleDVT factory from EasyTrack +19. Add new UpdateTargetValidatorLimits for SimpleDVT factory to EasyTrack + +Community Staking Module +20. Add Community Staking Module to Staking Router +21. Grant request burn role to CSAccounting +22. Grant resume role to Aragon Agent +23. Resume Community Staking Module +24. Revoke resume role from Aragon Agent +25. Update initial epoch on CSHashConsensus +26. Add CSMSettleElStealingPenalty factory to EasyTrack """ From d346a28eca1576446b641575ad710a2014908338 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Mon, 14 Oct 2024 13:55:49 +0500 Subject: [PATCH 154/220] free savings --- tests/acceptance/conftest.py | 4 ++-- tests/regression/conftest.py | 13 ++----------- tests/regression/test_accounting.py | 4 +--- .../test_accounting_oracle_extra_data_full_items.py | 4 ++-- tests/regression/test_csm.py | 1 - utils/test/node_operators_helpers.py | 2 +- 6 files changed, 8 insertions(+), 20 deletions(-) diff --git a/tests/acceptance/conftest.py b/tests/acceptance/conftest.py index a6cb26301..b51f84217 100644 --- a/tests/acceptance/conftest.py +++ b/tests/acceptance/conftest.py @@ -12,8 +12,8 @@ ENV_FILL_SIMPLE_DVT = "FILL_SIMPLE_DVT" -@pytest.fixture(scope="function", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) -def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger): +@pytest.fixture(scope="module", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) +def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger, module_isolation): if vote_ids_from_env: helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") else: diff --git a/tests/regression/conftest.py b/tests/regression/conftest.py index 2dae114e9..73d98a769 100644 --- a/tests/regression/conftest.py +++ b/tests/regression/conftest.py @@ -13,17 +13,8 @@ ENV_FILL_SIMPLE_DVT = "FILL_SIMPLE_DVT" -@pytest.fixture(scope="function", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) -def autoexecute_vote(request, helpers, vote_ids_from_env, accounts, stranger): - if "autoexecute_vote_ms" in request.node.fixturenames: - return - autoexecute_vote_impl(helpers, vote_ids_from_env, accounts, stranger) - -@pytest.fixture(scope="module") -def autoexecute_vote_ms(helpers, vote_ids_from_env, accounts, stranger): - autoexecute_vote_impl(helpers, vote_ids_from_env, accounts, stranger) - -def autoexecute_vote_impl(helpers, vote_ids_from_env, accounts, stranger): +@pytest.fixture(scope="module", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) +def autoexecute_vote(request, helpers, vote_ids_from_env, accounts, stranger, module_isolation): if vote_ids_from_env: helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") else: diff --git a/tests/regression/test_accounting.py b/tests/regression/test_accounting.py index a94679ddf..45c9ccfb0 100644 --- a/tests/regression/test_accounting.py +++ b/tests/regression/test_accounting.py @@ -1,4 +1,4 @@ -from typing import TypedDict, TypeVar, Any +from typing import TypeVar, Any import pytest from brownie import Contract, accounts, chain, reverts from brownie.network.account import Account @@ -24,8 +24,6 @@ LIMITER_PRECISION_BASE = 10**9 MAX_BASIS_POINTS = 10_000 -pytestmark = pytest.mark.usefixtures("autoexecute_vote_ms") - @pytest.fixture(scope="module") def accounting_oracle() -> Contract: return contracts.accounting_oracle diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 70a83f043..167e5748b 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -43,7 +43,7 @@ def sdvt(interface): @pytest.fixture(scope="module") -def prepare_modules(nor, sdvt, voting_eoa, agent_eoa, evm_script_executor_eoa, autoexecute_vote_ms): +def prepare_modules(nor, sdvt, voting_eoa, agent_eoa, evm_script_executor_eoa): # Fill NOR with new operators and keys (nor_count_before, added_nor_operators_count) = fill_nor_with_old_and_new_operators( nor, @@ -216,7 +216,7 @@ def test_extra_data_full_items( assert contracts.csm.getNodeOperatorSummary(i)["stuckValidatorsCount"] == csm_stuck[(3, i)] -def test_extra_data_most_expensive_report(autoexecute_vote_ms, extra_data_service): +def test_extra_data_most_expensive_report(extra_data_service): """ Make sure the worst report fits into the block gas limit. It needs to prepare a lot of node operators in a very special state, so it takes a lot of time to run. diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py index 1a1ae53fa..158cce008 100644 --- a/tests/regression/test_csm.py +++ b/tests/regression/test_csm.py @@ -21,7 +21,6 @@ CSM_MODULE_ID = 3 -pytestmark = pytest.mark.usefixtures("autoexecute_vote_ms") @pytest.fixture(scope="module") def csm(): diff --git a/utils/test/node_operators_helpers.py b/utils/test/node_operators_helpers.py index 193c3fd4a..f4a8c1505 100644 --- a/utils/test/node_operators_helpers.py +++ b/utils/test/node_operators_helpers.py @@ -85,7 +85,7 @@ def encode_event_arguments(event_signature: str, *event_args): def get_event_arg_types(event_signature: str): # extract args clause with brackets, i.e. (uin256,address) - event_args = next(iter(re.findall("\(.*\)", event_signature)), None) + event_args = next(iter(re.findall(r"(.*)", event_signature)), None) assert event_args is not None, f'Cant extract arguments from event signature "{event_signature}"' return event_args.strip("()").split(",") From 7d27a047628cf81da4ff0cf496171312d26231bf Mon Sep 17 00:00:00 2001 From: skhomuti Date: Mon, 14 Oct 2024 19:00:02 +0500 Subject: [PATCH 155/220] fix csm tests to not fail when the module is on live specify csm oracle initial epoch according to research forum post move roles checks to the specific tests fix for vote cost > 1 ether --- scripts/upgrade_sr_v2.py | 2 +- tests/acceptance/test_csm.py | 120 +++------------------------ tests/regression/test_permissions.py | 79 +++++++++++++++++- utils/import_current_votes.py | 4 +- utils/test/oracle_report_helpers.py | 13 ++- 5 files changed, 103 insertions(+), 115 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index e6bd5142e..4c0c46510 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -117,7 +117,7 @@ CS_TREASURY_FEE = 400 CS_MAX_DEPOSITS_PER_BLOCK = 30 CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 58050 # TODO: need to check +CS_ORACLE_INITIAL_EPOCH = 326715 # TODO: need to check description = """ Proposal to support SR 2.0 and CSM Module diff --git a/tests/acceptance/test_csm.py b/tests/acceptance/test_csm.py index bd3b1a341..774d16d41 100644 --- a/tests/acceptance/test_csm.py +++ b/tests/acceptance/test_csm.py @@ -1,6 +1,7 @@ import pytest from brownie import interface, web3, Wei # type: ignore +from brownie.convert.datatypes import HexString from utils.config import ( contracts, @@ -10,24 +11,19 @@ WITHDRAWAL_QUEUE, WITHDRAWAL_VAULT, WSTETH_TOKEN, - STAKING_ROUTER, AGENT, BURNER, CSM_ADDRESS, CS_ACCOUNTING_ADDRESS, - CS_GATE_SEAL_ADDRESS, - CS_VERIFIER_ADDRESS, CS_FEE_DISTRIBUTOR_ADDRESS, CS_FEE_ORACLE_ADDRESS, CS_ORACLE_HASH_CONSENSUS_ADDRESS, - EASYTRACK_EVMSCRIPT_EXECUTOR, CHAIN_SECONDS_PER_SLOT, CHAIN_GENESIS_TIME, CHAIN_SLOTS_PER_EPOCH, CS_ORACLE_EPOCHS_PER_FRAME, ORACLE_QUORUM, ORACLE_COMMITTEE, - CSM_COMMITTEE_MS ) contracts: ContractsLazyLoader = contracts @@ -85,31 +81,6 @@ def test_init_state(self, csm): assert not csm.isPaused(); assert not csm.publicRelease(); - assert csm.getNodeOperatorsCount() == 0; - - - def test_roles(self, csm): - assert csm.hasRole(csm.STAKING_ROUTER_ROLE(), STAKING_ROUTER) - assert csm.getRoleMemberCount(csm.STAKING_ROUTER_ROLE()) == 1 - - assert csm.hasRole(csm.DEFAULT_ADMIN_ROLE(), AGENT) - assert csm.getRoleMemberCount(csm.DEFAULT_ADMIN_ROLE()) == 1 - - assert csm.hasRole(csm.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) - assert csm.getRoleMemberCount(csm.PAUSE_ROLE()) == 1 - - assert csm.hasRole(csm.REPORT_EL_REWARDS_STEALING_PENALTY_ROLE(), CSM_COMMITTEE_MS) - assert csm.getRoleMemberCount(csm.REPORT_EL_REWARDS_STEALING_PENALTY_ROLE()) == 1 - - assert csm.hasRole(csm.SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE(), EASYTRACK_EVMSCRIPT_EXECUTOR) - assert csm.getRoleMemberCount(csm.SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE()) == 1 - - assert csm.hasRole(csm.VERIFIER_ROLE(), CS_VERIFIER_ADDRESS) - assert csm.getRoleMemberCount(csm.VERIFIER_ROLE()) == 1 - - assert csm.getRoleMemberCount(csm.RESUME_ROLE()) == 0 - assert csm.getRoleMemberCount(csm.MODULE_MANAGER_ROLE()) == 0 - assert csm.getRoleMemberCount(csm.RECOVERER_ROLE()) == 0 class TestAccounting: @@ -123,27 +94,6 @@ def test_initial_state(self, accounting): assert accounting.chargePenaltyRecipient() == AGENT assert not accounting.isPaused() - def test_roles(self, accounting): - assert accounting.hasRole(accounting.SET_BOND_CURVE_ROLE(), CSM_ADDRESS) - assert accounting.hasRole(accounting.SET_BOND_CURVE_ROLE(), CSM_COMMITTEE_MS) - assert accounting.getRoleMemberCount(accounting.SET_BOND_CURVE_ROLE()) == 2 - - assert accounting.hasRole(accounting.RESET_BOND_CURVE_ROLE(), CSM_ADDRESS) - assert accounting.hasRole(accounting.RESET_BOND_CURVE_ROLE(), CSM_COMMITTEE_MS) - assert accounting.getRoleMemberCount(accounting.RESET_BOND_CURVE_ROLE()) == 2 - - assert accounting.hasRole(accounting.DEFAULT_ADMIN_ROLE(), AGENT) - assert accounting.getRoleMemberCount(accounting.DEFAULT_ADMIN_ROLE()) == 1 - - assert accounting.hasRole(accounting.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) - assert accounting.getRoleMemberCount(accounting.PAUSE_ROLE()) == 1 - - assert accounting.getRoleMemberCount(accounting.RESUME_ROLE()) == 0 - assert accounting.getRoleMemberCount(accounting.ACCOUNTING_MANAGER_ROLE()) == 0 - assert accounting.getRoleMemberCount(accounting.MANAGE_BOND_CURVES_ROLE()) == 0 - assert accounting.getRoleMemberCount(accounting.RECOVERER_ROLE()) == 0 - - def test_allowances(self, lido): uin256_max = 2 ** 256 - 1 assert lido.allowance(CS_ACCOUNTING_ADDRESS, WSTETH_TOKEN) == uin256_max @@ -156,16 +106,6 @@ def test_initial_state(self, fee_distributor): assert fee_distributor.STETH() == LIDO assert fee_distributor.ACCOUNTING() == CS_ACCOUNTING_ADDRESS assert fee_distributor.ORACLE() == CS_FEE_ORACLE_ADDRESS - assert fee_distributor.totalClaimableShares() == 0 - assert fee_distributor.pendingSharesToDistribute() == 0 - assert fee_distributor.treeRoot() == _str_to_bytes32("") - assert fee_distributor.treeCid() == "" - - def test_roles(self, fee_distributor): - assert fee_distributor.hasRole(fee_distributor.DEFAULT_ADMIN_ROLE(), AGENT) - assert fee_distributor.getRoleMemberCount(fee_distributor.DEFAULT_ADMIN_ROLE()) == 1 - - assert fee_distributor.getRoleMemberCount(fee_distributor.RECOVERER_ROLE()) == 0 class TestFeeOracle: @@ -177,68 +117,31 @@ def test_initial_state(self, fee_oracle): assert fee_oracle.getContractVersion() == 1 assert fee_oracle.getConsensusContract() == CS_ORACLE_HASH_CONSENSUS_ADDRESS assert fee_oracle.getConsensusVersion() == 1 - assert fee_oracle.getLastProcessingRefSlot() == 0 assert fee_oracle.avgPerfLeewayBP() == 500 assert not fee_oracle.isPaused() - report = fee_oracle.getConsensusReport() - assert report["hash"] == _str_to_bytes32("") - assert report["refSlot"] == 0 - assert report["processingDeadlineTime"] == 0 - assert not report["processingStarted"] - - - def test_roles(self, fee_oracle): - assert fee_oracle.hasRole(fee_oracle.DEFAULT_ADMIN_ROLE(), AGENT) - assert fee_oracle.getRoleMemberCount(fee_oracle.DEFAULT_ADMIN_ROLE()) == 1 - - assert fee_oracle.hasRole(fee_oracle.PAUSE_ROLE(), CS_GATE_SEAL_ADDRESS) - assert fee_oracle.getRoleMemberCount(fee_oracle.PAUSE_ROLE()) == 1 - - assert fee_oracle.getRoleMemberCount(fee_oracle.CONTRACT_MANAGER_ROLE()) == 0 - assert fee_oracle.getRoleMemberCount(fee_oracle.SUBMIT_DATA_ROLE()) == 0 - assert fee_oracle.getRoleMemberCount(fee_oracle.RESUME_ROLE()) == 0 - assert fee_oracle.getRoleMemberCount(fee_oracle.RECOVERER_ROLE()) == 0 - class TestHashConsensus: def test_initial_state(self, hash_consensus): - current_frame = hash_consensus.getCurrentFrame() - # TODO uncomment this when initial ref slot is known - # assert current_frame["refSlot"] > 5254400 - # assert current_frame["reportProcessingDeadlineSlot"] > 5254400 - chain_config = hash_consensus.getChainConfig() assert chain_config["slotsPerEpoch"] == CHAIN_SLOTS_PER_EPOCH assert chain_config["secondsPerSlot"] == CHAIN_SECONDS_PER_SLOT assert chain_config["genesisTime"] == CHAIN_GENESIS_TIME frame_config = hash_consensus.getFrameConfig() - # TODO uncomment this when initial ref slot is known - # assert frame_config["initialEpoch"] > 5254400 / CHAIN_SLOTS_PER_EPOCH + assert frame_config["initialEpoch"] >= 326715 assert frame_config["epochsPerFrame"] == CS_ORACLE_EPOCHS_PER_FRAME assert frame_config["fastLaneLengthSlots"] == 1800 assert hash_consensus.getQuorum() == ORACLE_QUORUM - # TODO uncomment this when initial ref slot is known - # assert hash_consensus.getInitialRefSlot() > 5254400 + assert hash_consensus.getInitialRefSlot() >= 326715 * CHAIN_SLOTS_PER_EPOCH - 1 members = hash_consensus.getMembers() assert sorted(members["addresses"]) == sorted(ORACLE_COMMITTEE) assert hash_consensus.getReportProcessor() == CS_FEE_ORACLE_ADDRESS - def test_roles(self, hash_consensus): - assert hash_consensus.hasRole(hash_consensus.DEFAULT_ADMIN_ROLE(), AGENT) - assert hash_consensus.getRoleMemberCount(hash_consensus.DEFAULT_ADMIN_ROLE()) == 1 - - assert hash_consensus.getRoleMemberCount(hash_consensus.MANAGE_MEMBERS_AND_QUORUM_ROLE()) == 0 - assert hash_consensus.getRoleMemberCount(hash_consensus.DISABLE_CONSENSUS_ROLE()) == 0 - assert hash_consensus.getRoleMemberCount(hash_consensus.MANAGE_FRAME_CONFIG_ROLE()) == 0 - assert hash_consensus.getRoleMemberCount(hash_consensus.MANAGE_FAST_LANE_CONFIG_ROLE()) == 0 - assert hash_consensus.getRoleMemberCount(hash_consensus.MANAGE_REPORT_PROCESSOR_ROLE()) == 0 - def test_early_adoption_state(early_adoption): assert early_adoption.MODULE() == CSM_ADDRESS assert early_adoption.CURVE_ID() == 1 @@ -247,11 +150,12 @@ def test_verifier_state(verifier): assert verifier.WITHDRAWAL_ADDRESS() == WITHDRAWAL_VAULT assert verifier.MODULE() == CSM_ADDRESS assert verifier.SLOTS_PER_EPOCH() == CHAIN_SLOTS_PER_EPOCH - # TODO uncomment this when values are known - # assert verifier.GI_HISTORICAL_SUMMARIES_PREV() == "" - # assert verifier.GI_HISTORICAL_SUMMARIES_CURR() == "" - # assert verifier.GI_FIRST_WITHDRAWAL_PREV() == "" - # assert verifier.GI_FIRST_WITHDRAWAL_CURR() == "" - # assert verifier.GI_FIRST_VALIDATOR_PREV() == "" - # assert verifier.GI_FIRST_VALIDATOR_CURR() == "" - # assert verifier.FIRST_SUPPORTED_SLOT() == "" + print(type(verifier.GI_HISTORICAL_SUMMARIES_PREV())) + assert verifier.GI_HISTORICAL_SUMMARIES_PREV() == HexString("0x0000000000000000000000000000000000000000000000000000000000003b00", "bytes") + assert verifier.GI_HISTORICAL_SUMMARIES_CURR() == HexString("0x0000000000000000000000000000000000000000000000000000000000003b00", "bytes") + assert verifier.GI_FIRST_WITHDRAWAL_PREV() == HexString("0x0000000000000000000000000000000000000000000000000000000000e1c004", "bytes") + assert verifier.GI_FIRST_WITHDRAWAL_CURR() == HexString("0x0000000000000000000000000000000000000000000000000000000000e1c004", "bytes") + assert verifier.GI_FIRST_VALIDATOR_PREV() == HexString("0x0000000000000000000000000000000000000000000000000056000000000028", "bytes") + assert verifier.GI_FIRST_VALIDATOR_CURR() == HexString("0x0000000000000000000000000000000000000000000000000056000000000028", "bytes") + assert verifier.FIRST_SUPPORTED_SLOT() == 8626176 + assert verifier.PIVOT_SLOT() == 8626176 diff --git a/tests/regression/test_permissions.py b/tests/regression/test_permissions.py index 45caae860..3a8d8a47a 100644 --- a/tests/regression/test_permissions.py +++ b/tests/regression/test_permissions.py @@ -9,14 +9,14 @@ from brownie import interface, convert, web3 from brownie.network.event import _decode_logs from brownie.network.state import TxHistory -from utils.test.event_validators.permission import Permission + +from configs.config_mainnet import CSM_COMMITTEE_MS from utils.test.helpers import ZERO_BYTES32 from brownie.exceptions import EventLookupError from utils.config import ( contracts, GATE_SEAL, DSM_GUARDIANS, - EASYTRACK_EVMSCRIPT_EXECUTOR, ORACLE_COMMITTEE, AGENT, EASYTRACK_EVMSCRIPT_EXECUTOR, @@ -42,6 +42,13 @@ LIDO_LOCATOR, LEGACY_ORACLE, SIMPLE_DVT, + CSM_ADDRESS, + CS_ACCOUNTING_ADDRESS, + CS_GATE_SEAL_ADDRESS, + CS_VERIFIER_ADDRESS, + CS_FEE_DISTRIBUTOR_ADDRESS, + CS_FEE_ORACLE_ADDRESS, + CS_ORACLE_HASH_CONSENSUS_ADDRESS, ) @@ -300,6 +307,74 @@ def protocol_permissions(): "type": "AragonApp", "roles": {}, }, + CSM_ADDRESS: { + "contract_name": "CSModule", + "contract": contracts.csm, + "type": "CustomApp", + "roles": { + "DEFAULT_ADMIN_ROLE": [contracts.agent], + "STAKING_ROUTER_ROLE": [STAKING_ROUTER], + "PAUSE_ROLE": [CS_GATE_SEAL_ADDRESS], + "REPORT_EL_REWARDS_STEALING_PENALTY_ROLE": [CSM_COMMITTEE_MS], + "SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE": [EASYTRACK_EVMSCRIPT_EXECUTOR], + "VERIFIER_ROLE": [CS_VERIFIER_ADDRESS], + "RESUME_ROLE": [], + "MODULE_MANAGER_ROLE": [], + "RECOVERER_ROLE": [], + }, + }, + CS_ACCOUNTING_ADDRESS: { + "contract_name": "CSAccounting", + "contract": contracts.cs_accounting, + "type": "CustomApp", + "roles": { + "DEFAULT_ADMIN_ROLE": [contracts.agent], + "SET_BOND_CURVE_ROLE": [CSM_ADDRESS, CSM_COMMITTEE_MS], + "RESET_BOND_CURVE_ROLE": [CSM_ADDRESS, CSM_COMMITTEE_MS], + "PAUSE_ROLE": [CS_GATE_SEAL_ADDRESS], + "RESUME_ROLE": [], + "ACCOUNTING_MANAGER_ROLE": [], + "MANAGE_BOND_CURVES_ROLE": [], + "RECOVERER_ROLE": [], + }, + }, + CS_FEE_DISTRIBUTOR_ADDRESS: { + "contract_name": "CSFeeDistributor", + "contract": contracts.cs_fee_distributor, + "type": "CustomApp", + "roles": { + "DEFAULT_ADMIN_ROLE": [contracts.agent], + "RECOVERER_ROLE": [], + }, + }, + CS_FEE_ORACLE_ADDRESS: { + "contract_name": "CSFeeOracle", + "contract": contracts.cs_fee_oracle, + "type": "CustomApp", + "roles": { + "DEFAULT_ADMIN_ROLE": [contracts.agent], + "MANAGE_CONSENSUS_CONTRACT_ROLE": [], + "MANAGE_CONSENSUS_VERSION_ROLE": [], + "PAUSE_ROLE": [CS_GATE_SEAL_ADDRESS], + "CONTRACT_MANAGER_ROLE": [], + "SUBMIT_DATA_ROLE": [], + "RESUME_ROLE": [], + "RECOVERER_ROLE": [], + }, + }, + CS_ORACLE_HASH_CONSENSUS_ADDRESS: { + "contract_name": "HashConsensus", + "contract": contracts.csm_hash_consensus, + "type": "CustomApp", + "roles": { + "DEFAULT_ADMIN_ROLE": [contracts.agent], + "MANAGE_MEMBERS_AND_QUORUM_ROLE": [], + "DISABLE_CONSENSUS_ROLE": [], + "MANAGE_FRAME_CONFIG_ROLE": [], + "MANAGE_FAST_LANE_CONFIG_ROLE": [], + "MANAGE_REPORT_PROCESSOR_ROLE": [], + }, + } } diff --git a/utils/import_current_votes.py b/utils/import_current_votes.py index d7269b8d2..159b2fa00 100644 --- a/utils/import_current_votes.py +++ b/utils/import_current_votes.py @@ -62,8 +62,8 @@ def start_and_execute_votes(dao_voting, helpers) -> tuple[List[str], List[Transa # otherwise start_vote will fail with ValueError: Insufficient funds for gas * price + value # check voting.py: tx = token_manager.forward(new_vote_script, tx_params) ldo_holder_for_test = accounts.at(LDO_HOLDER_ADDRESS_FOR_TESTS, True) - if ldo_holder_for_test.balance() < ETH(1): - accounts[0].transfer(LDO_HOLDER_ADDRESS_FOR_TESTS, "1 ether") + if ldo_holder_for_test.balance() < ETH(10): + accounts[0].transfer(LDO_HOLDER_ADDRESS_FOR_TESTS, "10 ether") vote_id, _ = start_vote({"from": LDO_HOLDER_ADDRESS_FOR_TESTS}, silent=True) (tx,) = helpers.execute_votes(accounts, [vote_id], dao_voting, topup="0.5 ether") diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index 2433b0be7..b0d90bdf7 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -296,10 +296,19 @@ def simulate_report( def wait_to_next_available_report_time(consensus_contract): (SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME) = consensus_contract.getChainConfig() - (refSlot, _) = consensus_contract.getCurrentFrame() + try: + (refSlot, _) = consensus_contract.getCurrentFrame() + except VirtualMachineError as e: + if "InitialEpochIsYetToArrive" in str(e): + frame_config = consensus_contract.getFrameConfig() + chain.sleep(GENESIS_TIME + 1 + (frame_config["initialEpoch"] * SLOTS_PER_EPOCH * SECONDS_PER_SLOT) - chain.time()) + chain.mine(1) + (refSlot, _) = consensus_contract.getCurrentFrame() + else: + raise time = chain.time() (_, EPOCHS_PER_FRAME, _) = consensus_contract.getFrameConfig() - frame_start_with_offset = GENESIS_TIME + (refSlot + SLOTS_PER_EPOCH * EPOCHS_PER_FRAME + 1) * SECONDS_PER_SLOT + frame_start_with_offset = GENESIS_TIME + (refSlot + SLOTS_PER_EPOCH * EPOCHS_PER_FRAME + 1) * SECONDS_PER_SLOT + 1 chain.sleep(frame_start_with_offset - time) chain.mine(1) (nextRefSlot, _) = consensus_contract.getCurrentFrame() From 7a33a05ec7f93efbc41e810879f5603e4a2862d1 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Tue, 15 Oct 2024 03:24:21 +0400 Subject: [PATCH 156/220] fix: fix contract addresses and prameters in a voting test --- configs/config_mainnet.py | 7 +- scripts/upgrade_sr_v2.py | 66 ++++---- tests/test_upgrade_sr_v2.py | 307 ++++++++++++++++++++++-------------- 3 files changed, 223 insertions(+), 157 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index f4dd0260a..21e545e9e 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -246,7 +246,7 @@ # "0xEC4BfbAF681eb505B94E4a7849877DC6c600Ca3A", Excluded from members in vote 2024/08/06 "0x61c91ECd902EB56e314bB2D5c5C07785444Ea1c8", "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d", - "0xe57B3792aDCc5da47EF4fF588883F0ee0c9835C9" # Added into members in vote 2024/08/06 + "0xe57B3792aDCc5da47EF4fF588883F0ee0c9835C9", # Added into members in vote 2024/08/06 ) # WithdrawalQueueERC721 @@ -267,7 +267,7 @@ STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" STAKING_ROUTER_IMPL = "0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA" -STAKING_ROUTER_VERSION = 2 # do we need set this value now ? +STAKING_ROUTER_VERSION = 2 # Not a precise but still some estimation of the fees. Assume here that both modules are filled @@ -325,7 +325,7 @@ SDVT_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" -#CSM +# CSM CS_ORACLE_EPOCHS_PER_FRAME = 225 * 28 # 28 days CS_MODULE_ID = 3 CS_MODULE_NAME = "Community Staking" @@ -345,4 +345,3 @@ CS_FEE_ORACLE_ADDRESS = "0x4D4074628678Bd302921c20573EEa1ed38DdF7FB" CS_GATE_SEAL_ADDRESS = "0x5cFCa30450B1e5548F140C24A47E36c10CE306F0" CS_VERIFIER_ADDRESS = "0x3Dfc50f22aCA652a0a6F28a0F892ab62074b5583" - diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index e6bd5142e..f87b12c91 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -52,6 +52,22 @@ ACCOUNTING_ORACLE_IMPL, NODE_OPERATORS_REGISTRY_IMPL, CS_ACCOUNTING_ADDRESS, + EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY, + CURATED_STAKING_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, + SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, + CURATED_STAKING_MODULE_MAX_DEPOSITS_PER_BLOCK, + SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK, + CS_MODULE_MAX_DEPOSITS_PER_BLOCK, + CURATED_STAKING_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE, + SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE, + CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE, + AO_CONSENSUS_VERSION, + VEBO_CONSENSUS_VERSION, + CS_MODULE_NAME, + CS_MODULE_TARGET_SHARE_BP, + CS_MODULE_MODULE_FEE_BP, + CS_MODULE_TREASURY_FEE_BP, ) from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description from utils.repo import ( @@ -76,48 +92,32 @@ ## Easy track OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" -NEW_TARGET_LIMIT_FACTORY = "0x161a4552A625844c822954C5AcBac928ee0f399B" ## Curated module nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" -CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10_000 -CURATED_MAX_DEPOSITS_PER_BLOCK = 150 -CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 NOR_VERSION_REPO = ["5", "0", "0"] -### RewardDistributionState -DISTRIBUTED = 2 - ## SDVT module sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" -SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 444 -SDVT_MAX_DEPOSITS_PER_BLOCK = 150 -SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 SDVT_VERSION_REPO = ["2", "0", "0"] ## SR -PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS] -MAX_DEPOSITS_PER_BLOCK = [CURATED_MAX_DEPOSITS_PER_BLOCK, SDVT_MAX_DEPOSITS_PER_BLOCK] -MIN_DEPOSIT_BLOCK_DISTANCES = [CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, SDVT_MIN_DEPOSIT_BLOCK_DISTANCES] - -## Accounting oracle -AO_CONSENSUS_VERSION = 2 -## Vebo -VEBO_CONSENSUS_VERSION = 2 +PRIORITY_EXIT_SHARE_THRESHOLDS_BP = [ + CURATED_STAKING_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, + SIMPLE_DVT_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, +] +MAX_DEPOSITS_PER_BLOCK = [CURATED_STAKING_MODULE_MAX_DEPOSITS_PER_BLOCK, SIMPLE_DVT_MODULE_MAX_DEPOSITS_PER_BLOCK] +MIN_DEPOSIT_BLOCK_DISTANCES = [ + CURATED_STAKING_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE, + SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE, +] # CSM ## Easy track EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" ## Parameters -CS_MODULE_NAME = "Community Staking" -CS_STAKE_SHARE_LIMIT = 100 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 125 -CS_STAKING_MODULE_FEE = 600 -CS_TREASURY_FEE = 400 -CS_MAX_DEPOSITS_PER_BLOCK = 30 -CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 58050 # TODO: need to check +CS_ORACLE_INITIAL_EPOCH = 326715 description = """ Proposal to support SR 2.0 and CSM Module @@ -334,7 +334,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ( "19. Add new UpdateTargetValidatorLimits for SimpleDVT factory to EasyTrack", add_evmscript_factory( - factory=NEW_TARGET_LIMIT_FACTORY, + factory=EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY, permissions=( create_permissions_for_overloaded_method( contracts.simple_dvt, "updateTargetValidatorsLimits", ("uint", "uint", "uint") @@ -353,12 +353,12 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T contracts.staking_router.addStakingModule.encode_input( CS_MODULE_NAME, contracts.csm.address, - CS_STAKE_SHARE_LIMIT, - CS_PRIORITY_EXIT_SHARE_THRESHOLD, - CS_STAKING_MODULE_FEE, - CS_TREASURY_FEE, - CS_MAX_DEPOSITS_PER_BLOCK, - CS_MIN_DEPOSIT_BLOCK_DISTANCE, + CS_MODULE_TARGET_SHARE_BP, + CS_MODULE_PRIORITY_EXIT_SHARE_THRESHOLD, + CS_MODULE_MODULE_FEE_BP, + CS_MODULE_TREASURY_FEE_BP, + CS_MODULE_MAX_DEPOSITS_PER_BLOCK, + CS_MODULE_MIN_DEPOSIT_BLOCK_DISTANCE, ), ), ] diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index e90a8ad0a..de850bfb3 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -1,52 +1,7 @@ import pytest -from utils.config import ( - contracts, - STAKING_ROUTER_IMPL, - LIDO_LOCATOR_IMPL, - NODE_OPERATORS_REGISTRY_IMPL, - NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, - NODE_OPERATORS_REGISTRY, - SIMPLE_DVT, - SIMPLE_DVT_ARAGON_APP_ID, - SIMPLE_DVT_IMPL, - ACCOUNTING_ORACLE_IMPL, - CS_ACCOUNTING_ADDRESS, - CSM_ADDRESS, -) -from scripts.upgrade_sr_v2 import ( - start_vote, - # oracles - AO_CONSENSUS_VERSION, - VEBO_CONSENSUS_VERSION, - # nor - nor_uri, - CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, - CURATED_MAX_DEPOSITS_PER_BLOCK, - CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, - # sdvt - sdvt_uri, - SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS, - SDVT_MAX_DEPOSITS_PER_BLOCK, - SDVT_MIN_DEPOSIT_BLOCK_DISTANCES, - ## easy track - OLD_TARGET_LIMIT__FACTORY, - NEW_TARGET_LIMIT_FACTORY, - # CSM - CS_MODULE_NAME, - CS_STAKE_SHARE_LIMIT, - CS_PRIORITY_EXIT_SHARE_THRESHOLD, - CS_STAKING_MODULE_FEE, - CS_TREASURY_FEE, - CS_MAX_DEPOSITS_PER_BLOCK, - CS_MIN_DEPOSIT_BLOCK_DISTANCE, - CS_ORACLE_INITIAL_EPOCH, - EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, -) -from utils.config import ( - contracts, - LDO_HOLDER_ADDRESS_FOR_TESTS, -) +from scripts.upgrade_sr_v2 import start_vote +from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS from brownie import interface, Contract from utils.test.tx_tracing_helpers import * from utils.test.event_validators.permission import validate_grant_role_event, validate_revoke_role_event @@ -61,12 +16,67 @@ ) from utils.easy_track import create_permissions, create_permissions_overloaded -# Impl addresses before vote +# Addresses that will not be changed + +NODE_OPERATORS_REGISTRY = "0x55032650b14df07b85bF18A3a3eC8E0Af2e028d5" +SIMPLE_DVT = "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" +LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" +STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" +ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" +VALIDATORS_EXIT_BUS_ORACLE = "0x0De4Ea0184c2ad0BacA7183356Aea5B8d5Bf5c6e" +AGENT = "0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c" +BURNER = "0xD15a672319Cf0352560eE76d9e89eAB0889046D3" +VOTING = "0x2e59A20f205bB85a89C53f1936454680651E618e" + +# aragon repo +NODE_OPERATORS_REGISTRY_REPO = "0x0D97E876ad14DB2b183CFeEB8aa1A5C788eB1831" +SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" + +# Addresses before vote OLD_LOCATOR_IMPL_ADDRESS = "0x39aFE23cE59e8Ef196b81F0DCb165E9aD38b9463" OLD_SR_IMPL_ADDRESS = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" OLD_NOR_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" OLD_SDVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" OLD_ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" +DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" + +# Addresses after vote +NEW_LIDO_LOCATOR_IMPL = "0x3ABc4764f0237923d52056CFba7E9AEBf87113D3" +NEW_STAKING_ROUTER_IMPL = "0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA" +NEW_NODE_OPERATORS_REGISTRY_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" +NEW_SIMPLE_DVT_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" +NEW_ACCOUNTING_ORACLE_IMPL = "0x0e65898527E77210fB0133D00dd4C0E86Dc29bC7" +DEPOSIT_SECURITY_MODULE_V3 = "0xffa96d84def2ea035c7ab153d8b991128e3d72fd" + +# Easy track sdvt +OLD_TARGET_LIMIT_FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" +NEW_TARGET_LIMIT_FACTORY = "0x161a4552A625844c822954C5AcBac928ee0f399B" + +# CSM +CSM_ADDRESS = "0xdA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F" +CS_ACCOUNTING_ADDRESS = "0x4d72BFF1BeaC69925F8Bd12526a39BAAb069e5Da" +CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0x71093efF8D8599b5fA340D665Ad60fA7C80688e4" + +# Staking Router parameters +nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" +CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10_000 +CURATED_MAX_DEPOSITS_PER_BLOCK = 150 +CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 + +sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" +SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 444 +SDVT_MAX_DEPOSITS_PER_BLOCK = 150 +SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 + +# aragor id +NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" +SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" + + +# Accounting oracle +AO_CONSENSUS_VERSION = 2 +# Vebo +VEBO_CONSENSUS_VERSION = 2 # NOR ### RewardDistributionState @@ -78,6 +88,20 @@ SDVT_VERSION = 3 AO_VERSION = 2 +# CSM parameters + +CS_MODULE_NAME = "Community Staking" +CS_STAKE_SHARE_LIMIT = 100 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 125 +CS_STAKING_MODULE_FEE = 600 +CS_TREASURY_FEE = 400 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 326715 + +# CSM steaking penalty factory +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" + # Roles ## SR STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" @@ -190,14 +214,18 @@ def test_vote( accounts, vote_ids_from_env, ): - staking_router = contracts.staking_router - sr_proxy = interface.OssifiableProxy(contracts.staking_router) - locator_proxy = interface.OssifiableProxy(contracts.lido_locator) - nor_proxy = interface.AppProxyUpgradeable(contracts.node_operators_registry) - sdvt_proxy = interface.AppProxyUpgradeable(contracts.simple_dvt) - ao_proxy = interface.OssifiableProxy(contracts.accounting_oracle) - vebo_proxy = interface.ValidatorsExitBusOracle(contracts.validators_exit_bus_oracle) - + sr_proxy = interface.OssifiableProxy(STAKING_ROUTER) + locator_proxy = interface.OssifiableProxy(LIDO_LOCATOR) + nor_proxy = interface.AppProxyUpgradeable(NODE_OPERATORS_REGISTRY) + sdvt_proxy = interface.AppProxyUpgradeable(SIMPLE_DVT) + ao_proxy = interface.OssifiableProxy(ACCOUNTING_ORACLE) + vebo = get_vebo() + burner = get_burner() + csm = get_csm() + csm_hash_consensus = get_csm_hash_consensus() + + # TODO: staking router change + staking_router = get_staking_router() assert staking_router.getStakingModulesCount() == 2 # Before voting tests @@ -210,11 +238,13 @@ def test_vote( check_module_before_vote(CURATED_MODULE_BEFORE_VOTE) check_module_before_vote(SDVT_MODULE_BEFORE_VOTE) # NOR - nor_old_app = contracts.nor_app_repo.getLatest() + nor_app_repo = interface.Repo(NODE_OPERATORS_REGISTRY_REPO) + nor_old_app = nor_app_repo.getLatest() assert nor_proxy.implementation() == OLD_NOR_IMPL assert_repo_before_vote(nor_old_app, 4, OLD_NOR_IMPL, nor_uri) # SDVT - sdvt_old_app = contracts.simple_dvt_app_repo.getLatest() + sdvt_app_repo = interface.Repo(SIMPLE_DVT_REPO) + sdvt_old_app = sdvt_app_repo.getLatest() assert sdvt_proxy.implementation() == OLD_SDVT_IMPL assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, sdvt_uri) # AO @@ -223,9 +253,9 @@ def test_vote( check_manage_consensus_role() # VEBO consensus version - assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 - assert not contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) - assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) + assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 + assert not burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + assert not csm.hasRole(RESUME_ROLE, AGENT) # START VOTE if len(vote_ids_from_env) > 0: @@ -234,44 +264,47 @@ def test_vote( tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS} vote_id, _ = start_vote(tx_params, silent=True) - vote_tx = helpers.execute_vote(accounts, vote_id, contracts.voting) + # TODO: do we need instead use contracts.voting that read address from config? + voting = get_voting() + + vote_tx = helpers.execute_vote(accounts, vote_id, voting) print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") assert staking_router.getStakingModulesCount() == 3 # locator - check_ossifiable_proxy_impl(locator_proxy, LIDO_LOCATOR_IMPL) + check_ossifiable_proxy_impl(locator_proxy, NEW_LIDO_LOCATOR_IMPL) # DSM check_dsm_roles_after_vote() # SR - check_ossifiable_proxy_impl(sr_proxy, STAKING_ROUTER_IMPL) + check_ossifiable_proxy_impl(sr_proxy, NEW_STAKING_ROUTER_IMPL) check_module_after_vote(CURATED_MODULE_AFTER_VOTE) check_module_after_vote(SDVT_MODULE_AFTER_VOTE) # AO - check_ossifiable_proxy_impl(ao_proxy, ACCOUNTING_ORACLE_IMPL) + check_ossifiable_proxy_impl(ao_proxy, NEW_ACCOUNTING_ORACLE_IMPL) # no permission to manage consensus version on agent check_manage_consensus_role() # VEBO consensus version - assert vebo_proxy.getConsensusVersion() == VEBO_CONSENSUS_VERSION + assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION - assert contracts.burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) - assert not contracts.csm.hasRole(RESUME_ROLE, contracts.agent.address) + assert burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + assert not csm.hasRole(RESUME_ROLE, AGENT) - assert contracts.csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + assert csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH check_csm() # Events check - # events = group_voting_events(vote_tx) - events = group_voting_events_from_receipt(vote_tx) + display_voting_events(vote_tx) + events = group_voting_events(vote_tx) assert len(events) == 26 - validate_upgrade_events(events[0], LIDO_LOCATOR_IMPL) + validate_upgrade_events(events[0], NEW_LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) - validate_upgrade_events(events[4], STAKING_ROUTER_IMPL) + validate_upgrade_events(events[4], NEW_STAKING_ROUTER_IMPL) validate_staking_module_update( events[5], @@ -301,42 +334,38 @@ def test_vote( ], ) - nor_new_app = contracts.nor_app_repo.getLatest() - assert_repo_update(nor_new_app, nor_old_app, NODE_OPERATORS_REGISTRY_IMPL, nor_uri) + nor_new_app = nor_app_repo.getLatest() + assert_repo_update(nor_new_app, nor_old_app, NEW_NODE_OPERATORS_REGISTRY_IMPL, nor_uri) validate_repo_upgrade_event(events[6], RepoUpgrade(6, nor_new_app[0])) - validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL) + validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NEW_NODE_OPERATORS_REGISTRY_IMPL) validate_nor_update(events[8], NOR_VERSION) - sdvt_new_app = contracts.simple_dvt_app_repo.getLatest() - assert_repo_update(sdvt_new_app, sdvt_old_app, SIMPLE_DVT_IMPL, sdvt_uri) + sdvt_new_app = sdvt_app_repo.getLatest() + assert_repo_update(sdvt_new_app, sdvt_old_app, NEW_SIMPLE_DVT_IMPL, sdvt_uri) validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) - validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, SIMPLE_DVT_IMPL) + validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, NEW_SIMPLE_DVT_IMPL) validate_nor_update(events[11], SDVT_VERSION) # AO - validate_upgrade_events(events[12], ACCOUNTING_ORACLE_IMPL) + validate_upgrade_events(events[12], NEW_ACCOUNTING_ORACLE_IMPL) validate_ao_update(events[13], AO_VERSION, AO_CONSENSUS_VERSION) - validate_grant_role_event( - events[14], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address - ) + validate_grant_role_event(events[14], MANAGE_CONSENSUS_VERSION_ROLE, AGENT, AGENT) validate_vebo_consensus_version_set(events[15]) - validate_revoke_role_event( - events[16], MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address, contracts.agent.address - ) + validate_revoke_role_event(events[16], MANAGE_CONSENSUS_VERSION_ROLE, AGENT, AGENT) - validate_evmscript_factory_removed_event(events[17], OLD_TARGET_LIMIT__FACTORY) + validate_evmscript_factory_removed_event(events[17], OLD_TARGET_LIMIT_FACTORY) + + simple_dvt = get_simple_dvt() validate_evmscript_factory_added_event( events[18], EVMScriptFactoryAdded( factory_addr=NEW_TARGET_LIMIT_FACTORY, permissions=( - create_permissions_overloaded( - contracts.simple_dvt, "updateTargetValidatorsLimits", "uint256,uint256,uint256" - ) + create_permissions_overloaded(simple_dvt, "updateTargetValidatorsLimits", "uint256,uint256,uint256") ), ), ) @@ -355,70 +384,103 @@ def test_vote( CSM_AFTER_VOTE["minDepositBlockDistance"], ), ) - validate_grant_role_event(events[20], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, contracts.agent.address) - validate_grant_role_event(events[21], RESUME_ROLE, contracts.agent.address, contracts.agent.address) + validate_grant_role_event(events[20], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, AGENT) + validate_grant_role_event(events[21], RESUME_ROLE, AGENT, AGENT) validate_resume_event(events[22]) - validate_revoke_role_event(events[23], RESUME_ROLE, contracts.agent.address, contracts.agent.address) + validate_revoke_role_event(events[23], RESUME_ROLE, AGENT, AGENT) validate_updateInitial_epoch(events[24]) validate_evmscript_factory_added_event( events[25], EVMScriptFactoryAdded( factory_addr=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, - permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), + permissions=(create_permissions(csm, "settleELRewardsStealingPenalty")), ), ["LogScriptCall", "EVMScriptFactoryAdded", "ScriptResult", "ExecuteVote"], ) +def get_staking_router(): + return interface.StakingRouter(STAKING_ROUTER) + + +def get_deposit_security_module_v3(): + return interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE_V3) + + +def get_deposit_security_module_v2(): + return interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE_V2) + + +def get_vebo(): + return interface.ValidatorsExitBusOracle(VALIDATORS_EXIT_BUS_ORACLE) + + +def get_simple_dvt(): + return interface.SimpleDVT(SIMPLE_DVT) + + +def get_burner(): + return interface.Burner(BURNER) + + +def get_csm(): + return interface.CSModule(CSM_ADDRESS) + + +def get_voting(): + return interface.Voting(VOTING) + + +def get_csm_hash_consensus(): + return interface.CSHashConsensus(CS_ORACLE_HASH_CONSENSUS_ADDRESS) + + def check_ossifiable_proxy_impl(proxy, expected_impl): current_impl_address = proxy.proxy__getImplementation() assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" def check_dsm_roles_before_vote(): - new_dsm_doesnt_have_unvet_role = contracts.staking_router.hasRole( - STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module - ) + staking_router = get_staking_router() + deposit_security_module_v2 = get_deposit_security_module_v2() + deposit_security_module_v3 = get_deposit_security_module_v3() + new_dsm_doesnt_have_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) assert not new_dsm_doesnt_have_unvet_role - old_dsm_has_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) + old_dsm_has_pause_role = staking_router.hasRole(PAUSE_ROLE, deposit_security_module_v2) assert old_dsm_has_pause_role - old_dsm_has_resume_role = contracts.staking_router.hasRole( - STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 - ) + old_dsm_has_resume_role = staking_router.hasRole(STAKING_MODULE_RESUME_ROLE, deposit_security_module_v2) assert old_dsm_has_resume_role def check_dsm_roles_after_vote(): - new_dsm_has_unvet_role = contracts.staking_router.hasRole( - STAKING_MODULE_UNVETTING_ROLE, contracts.deposit_security_module - ) + staking_router = get_staking_router() + deposit_security_module_v2 = get_deposit_security_module_v2() + deposit_security_module_v3 = get_deposit_security_module_v3() + new_dsm_has_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) assert new_dsm_has_unvet_role - old_dsm_doesnt_have_pause_role = contracts.staking_router.hasRole(PAUSE_ROLE, contracts.deposit_security_module_v2) + old_dsm_doesnt_have_pause_role = staking_router.hasRole(PAUSE_ROLE, deposit_security_module_v2) assert not old_dsm_doesnt_have_pause_role - old_dsm_doesnt_have_resume_role = contracts.staking_router.hasRole( - STAKING_MODULE_RESUME_ROLE, contracts.deposit_security_module_v2 - ) + old_dsm_doesnt_have_resume_role = staking_router.hasRole(STAKING_MODULE_RESUME_ROLE, deposit_security_module_v2) assert not old_dsm_doesnt_have_resume_role def check_manage_consensus_role(): - agent_has_manage_consensus_role = contracts.validators_exit_bus_oracle.hasRole( - MANAGE_CONSENSUS_VERSION_ROLE, contracts.agent.address - ) + vebo = get_vebo() + agent_has_manage_consensus_role = vebo.hasRole(MANAGE_CONSENSUS_VERSION_ROLE, AGENT) assert not agent_has_manage_consensus_role def check_module_before_vote(expected_module_data: Dict): - sr_contract = Contract.from_abi("StakingContract", contracts.staking_router.address, OLD_SR_ABI) - module = sr_contract.getStakingModule(expected_module_data["id"]) + staking_router = Contract.from_abi("StakingContract", STAKING_ROUTER, OLD_SR_ABI) + module = staking_router.getStakingModule(expected_module_data["id"]) assert module["id"] == expected_module_data["id"] assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] assert module["treasuryFee"] == expected_module_data["treasuryFee"] @@ -429,7 +491,8 @@ def check_module_before_vote(expected_module_data: Dict): def check_module_after_vote(expected_module_data: Dict): - module = contracts.staking_router.getStakingModule(expected_module_data["id"]) + staking_router = get_staking_router() + module = staking_router.getStakingModule(expected_module_data["id"]) assert module["id"] == expected_module_data["id"] assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] assert module["treasuryFee"] == expected_module_data["treasuryFee"] @@ -465,20 +528,23 @@ def validate_upgrade_events(events: EventDict, implementation: str): def validate_dsm_roles_events(events: list[EventDict]): validate_revoke_role_event( - events[1], PAUSE_ROLE, contracts.deposit_security_module_v2.address, contracts.agent.address + events[1], + PAUSE_ROLE, + DEPOSIT_SECURITY_MODULE_V2, + AGENT, ) validate_revoke_role_event( events[2], STAKING_MODULE_RESUME_ROLE, - contracts.deposit_security_module_v2.address, - contracts.agent.address, + DEPOSIT_SECURITY_MODULE_V2, + AGENT, ) validate_grant_role_event( events[3], STAKING_MODULE_UNVETTING_ROLE, - contracts.deposit_security_module.address, - contracts.agent.address, + DEPOSIT_SECURITY_MODULE_V3, + AGENT, ) @@ -625,7 +691,8 @@ def validate_module_add(event, csm: StakingModuleItem): def check_csm(): - cs = contracts.staking_router.getStakingModule(3) + staking_router = get_staking_router() + cs = staking_router.getStakingModule(3) assert cs["name"] == CSM_AFTER_VOTE["name"] assert cs["stakingModuleFee"] == CSM_AFTER_VOTE["stakingModuleFee"] From a9549f210769f3995e940ba0e88e74cbc79b0592 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Tue, 15 Oct 2024 12:49:51 +0500 Subject: [PATCH 157/220] downgrade pytest-check to fix internal error with pytest 6.* incompatibility --- poetry.lock | 104 ++++++++++++++++++++++--------------------------- pyproject.toml | 2 +- 2 files changed, 48 insertions(+), 58 deletions(-) diff --git a/poetry.lock b/poetry.lock index 18ed6cfeb..3c31f75fa 100644 --- a/poetry.lock +++ b/poetry.lock @@ -692,13 +692,13 @@ files = [ [[package]] name = "distlib" -version = "0.3.8" +version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, - {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, + {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, + {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, ] [[package]] @@ -1028,19 +1028,19 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "filelock" -version = "3.13.3" +version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.3-py3-none-any.whl", hash = "sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb"}, - {file = "filelock-3.13.3.tar.gz", hash = "sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546"}, + {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, + {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] -typing = ["typing-extensions (>=4.8)"] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] +typing = ["typing-extensions (>=4.12.2)"] [[package]] name = "frozenlist" @@ -1178,13 +1178,13 @@ zoneinfo = ["backports.zoneinfo (>=0.2.1)", "importlib-resources (>=3.3.0)", "tz [[package]] name = "identify" -version = "2.5.35" +version = "2.6.1" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.35-py2.py3-none-any.whl", hash = "sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e"}, - {file = "identify-2.5.35.tar.gz", hash = "sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791"}, + {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"}, + {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"}, ] [package.extras] @@ -1529,18 +1529,15 @@ files = [ [[package]] name = "nodeenv" -version = "1.8.0" +version = "1.9.1" description = "Node.js virtual environment builder" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, - {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] -[package.dependencies] -setuptools = "*" - [[package]] name = "packaging" version = "23.2" @@ -1819,13 +1816,13 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm [[package]] name = "pytest-check" -version = "2.2.3" +version = "2.2.2" description = "A pytest plugin that allows multiple failures per test." optional = false python-versions = ">=3.7" files = [ - {file = "pytest_check-2.2.3-py3-none-any.whl", hash = "sha256:d2643066fb805ca380b9251ef641a22dddc339018179a1e5f0b4626a5ff7e560"}, - {file = "pytest_check-2.2.3.tar.gz", hash = "sha256:6df03264b6bbcf25cd8615120cda03b4e6d11fdb2b7c8dde6a9c8fef18a7495c"}, + {file = "pytest_check-2.2.2-py3-none-any.whl", hash = "sha256:c51dd795e3a054734f6f779c5a3691985bd455007f9643eff0c2e743aff36552"}, + {file = "pytest_check-2.2.2.tar.gz", hash = "sha256:7ae7e99e90f127d3d02d29c02a8b2d95b5a87db3d30dccd169e9fd66c44fdbe8"}, ] [package.dependencies] @@ -1892,25 +1889,29 @@ files = [ [[package]] name = "pywin32" -version = "306" +version = "308" description = "Python for Window Extensions" optional = false python-versions = "*" files = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, + {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, + {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, + {file = "pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c"}, + {file = "pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a"}, + {file = "pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b"}, + {file = "pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6"}, + {file = "pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897"}, + {file = "pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47"}, + {file = "pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091"}, + {file = "pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed"}, + {file = "pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4"}, + {file = "pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd"}, + {file = "pywin32-308-cp37-cp37m-win32.whl", hash = "sha256:1f696ab352a2ddd63bd07430080dd598e6369152ea13a25ebcdd2f503a38f1ff"}, + {file = "pywin32-308-cp37-cp37m-win_amd64.whl", hash = "sha256:13dcb914ed4347019fbec6697a01a0aec61019c1046c2b905410d197856326a6"}, + {file = "pywin32-308-cp38-cp38-win32.whl", hash = "sha256:5794e764ebcabf4ff08c555b31bd348c9025929371763b2183172ff4708152f0"}, + {file = "pywin32-308-cp38-cp38-win_amd64.whl", hash = "sha256:3b92622e29d651c6b783e368ba7d6722b1634b8e70bd376fd7610fe1992e19de"}, + {file = "pywin32-308-cp39-cp39-win32.whl", hash = "sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341"}, + {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, ] [[package]] @@ -1925,7 +1926,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1933,16 +1933,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -1959,7 +1951,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -1967,7 +1958,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2315,13 +2305,13 @@ files = [ [[package]] name = "tomli" -version = "2.0.1" +version = "2.0.2" description = "A lil' TOML parser" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, + {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, ] [[package]] @@ -2385,13 +2375,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.25.1" +version = "20.26.6" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.25.1-py3-none-any.whl", hash = "sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a"}, - {file = "virtualenv-20.25.1.tar.gz", hash = "sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197"}, + {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"}, + {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"}, ] [package.dependencies] @@ -2400,7 +2390,7 @@ filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] @@ -2784,4 +2774,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.11" -content-hash = "0265d3ef8143b3be9fcb1e1261929fa0f8e02fbe8655df870fa22febb361e631" +content-hash = "cd154530d817fcf8aab4145d97fa6cf46ccc8d39cac7cdc18dc5e10001971d4b" diff --git a/pyproject.toml b/pyproject.toml index 7d5d17c83..d36828e64 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ ipfs-cid = "^1.0.0" [tool.poetry.dev-dependencies] black = "~24.2.0" pre-commit = "~2.19.0" -pytest-check = "^2.1.4" +pytest-check = "2.2.2" [build-system] requires = ["poetry-core>=1.0.0"] From c07ee2e3758e60bf95a27cf62faecedd53e1bf95 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Tue, 15 Oct 2024 13:00:34 +0400 Subject: [PATCH 158/220] fix: review --- scripts/rules | 3 +++ scripts/upgrade_sr_v2.py | 6 ++---- tests/test_upgrade_sr_v2.py | 33 ++++++++++++++++----------------- 3 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 scripts/rules diff --git a/scripts/rules b/scripts/rules new file mode 100644 index 000000000..3720fb056 --- /dev/null +++ b/scripts/rules @@ -0,0 +1,3 @@ +1. в тестах воутинга указать адреса явно и параметры +2. в воутинг скрипте импортируем из конфига +3. импортируем в скрипте адреса \ No newline at end of file diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index f87b12c91..6f62c6cb8 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -91,14 +91,12 @@ # SR ## Easy track -OLD_TARGET_LIMIT__FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" +OLD_TARGET_LIMIT_FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" ## Curated module -nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" NOR_VERSION_REPO = ["5", "0", "0"] ## SDVT module -sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" SDVT_VERSION_REPO = ["2", "0", "0"] ## SR @@ -328,7 +326,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ( "18. Remove old UpdateTargetValidatorLimits for SimpleDVT factory from EasyTrack", remove_evmscript_factory( - factory=OLD_TARGET_LIMIT__FACTORY, + factory=OLD_TARGET_LIMIT_FACTORY, ), ), ( diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index de850bfb3..c22ca9b27 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -58,17 +58,17 @@ CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0x71093efF8D8599b5fA340D665Ad60fA7C80688e4" # Staking Router parameters -nor_uri = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" +NOR_URI = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10_000 CURATED_MAX_DEPOSITS_PER_BLOCK = 150 CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 -sdvt_uri = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" +SDVT_URI = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 444 SDVT_MAX_DEPOSITS_PER_BLOCK = 150 SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 -# aragor id +# Aragon app ids NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" @@ -105,7 +105,7 @@ # Roles ## SR STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" -PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" +STAKING_MODULE_PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" @@ -224,7 +224,6 @@ def test_vote( csm = get_csm() csm_hash_consensus = get_csm_hash_consensus() - # TODO: staking router change staking_router = get_staking_router() assert staking_router.getStakingModulesCount() == 2 @@ -241,12 +240,12 @@ def test_vote( nor_app_repo = interface.Repo(NODE_OPERATORS_REGISTRY_REPO) nor_old_app = nor_app_repo.getLatest() assert nor_proxy.implementation() == OLD_NOR_IMPL - assert_repo_before_vote(nor_old_app, 4, OLD_NOR_IMPL, nor_uri) + assert_repo_before_vote(nor_old_app, 4, OLD_NOR_IMPL, NOR_URI) # SDVT sdvt_app_repo = interface.Repo(SIMPLE_DVT_REPO) sdvt_old_app = sdvt_app_repo.getLatest() assert sdvt_proxy.implementation() == OLD_SDVT_IMPL - assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, sdvt_uri) + assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, SDVT_URI) # AO check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) # no permission to manage consensus version on agent @@ -335,13 +334,13 @@ def test_vote( ) nor_new_app = nor_app_repo.getLatest() - assert_repo_update(nor_new_app, nor_old_app, NEW_NODE_OPERATORS_REGISTRY_IMPL, nor_uri) + assert_repo_update(nor_new_app, nor_old_app, NEW_NODE_OPERATORS_REGISTRY_IMPL, NOR_URI) validate_repo_upgrade_event(events[6], RepoUpgrade(6, nor_new_app[0])) validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NEW_NODE_OPERATORS_REGISTRY_IMPL) validate_nor_update(events[8], NOR_VERSION) sdvt_new_app = sdvt_app_repo.getLatest() - assert_repo_update(sdvt_new_app, sdvt_old_app, NEW_SIMPLE_DVT_IMPL, sdvt_uri) + assert_repo_update(sdvt_new_app, sdvt_old_app, NEW_SIMPLE_DVT_IMPL, SDVT_URI) validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, NEW_SIMPLE_DVT_IMPL) validate_nor_update(events[11], SDVT_VERSION) @@ -446,10 +445,10 @@ def check_dsm_roles_before_vote(): staking_router = get_staking_router() deposit_security_module_v2 = get_deposit_security_module_v2() deposit_security_module_v3 = get_deposit_security_module_v3() - new_dsm_doesnt_have_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) - assert not new_dsm_doesnt_have_unvet_role + new_dsm_has_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) + assert not new_dsm_has_unvet_role - old_dsm_has_pause_role = staking_router.hasRole(PAUSE_ROLE, deposit_security_module_v2) + old_dsm_has_pause_role = staking_router.hasRole(STAKING_MODULE_PAUSE_ROLE, deposit_security_module_v2) assert old_dsm_has_pause_role @@ -465,11 +464,11 @@ def check_dsm_roles_after_vote(): new_dsm_has_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) assert new_dsm_has_unvet_role - old_dsm_doesnt_have_pause_role = staking_router.hasRole(PAUSE_ROLE, deposit_security_module_v2) - assert not old_dsm_doesnt_have_pause_role + old_dsm_has_pause_role = staking_router.hasRole(STAKING_MODULE_PAUSE_ROLE, deposit_security_module_v2) + assert not old_dsm_has_pause_role - old_dsm_doesnt_have_resume_role = staking_router.hasRole(STAKING_MODULE_RESUME_ROLE, deposit_security_module_v2) - assert not old_dsm_doesnt_have_resume_role + old_dsm_has_resume_role = staking_router.hasRole(STAKING_MODULE_RESUME_ROLE, deposit_security_module_v2) + assert not old_dsm_has_resume_role def check_manage_consensus_role(): @@ -529,7 +528,7 @@ def validate_upgrade_events(events: EventDict, implementation: str): def validate_dsm_roles_events(events: list[EventDict]): validate_revoke_role_event( events[1], - PAUSE_ROLE, + STAKING_MODULE_PAUSE_ROLE, DEPOSIT_SECURITY_MODULE_V2, AGENT, ) From e56e8e1bbd369c0f6f6080dfd0e9bfc432eba31c Mon Sep 17 00:00:00 2001 From: skhomuti Date: Tue, 15 Oct 2024 13:19:13 +0500 Subject: [PATCH 159/220] take into account new easytrack motion in the snapshot tests --- tests/snapshot/test_first_slots.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/snapshot/test_first_slots.py b/tests/snapshot/test_first_slots.py index eea8e50d5..9fef98c6c 100644 --- a/tests/snapshot/test_first_slots.py +++ b/tests/snapshot/test_first_slots.py @@ -60,6 +60,9 @@ def skip_slots() -> Sequence[tuple[str, int]]: contracts.finance, 0x07, ), + # new EasyTrack factory for CSM (EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY) + # evmScriptFactories array + (contracts.easy_track.address, 5), ] @@ -81,7 +84,7 @@ def _get_slots(contract: Contract, block: int) -> dict: ) res[f"{contract.address}_slot_{slot_in_hex}"] = slot_value - # if the slot stores relativelly small integer, try to read as an array + # if the slot stores relatively small integer, try to read as an array int_value = Web3.to_int(slot_value) if 0 < int_value < MAX_ARRAY_SIZE: slot_value_as_list = get_slot( From 60a1f392df176b8024af414c54373e5a45d82168 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Tue, 15 Oct 2024 15:05:21 +0500 Subject: [PATCH 160/220] revert extra change --- utils/test/oracle_report_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index b0d90bdf7..8189c8296 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -308,7 +308,7 @@ def wait_to_next_available_report_time(consensus_contract): raise time = chain.time() (_, EPOCHS_PER_FRAME, _) = consensus_contract.getFrameConfig() - frame_start_with_offset = GENESIS_TIME + (refSlot + SLOTS_PER_EPOCH * EPOCHS_PER_FRAME + 1) * SECONDS_PER_SLOT + 1 + frame_start_with_offset = GENESIS_TIME + (refSlot + SLOTS_PER_EPOCH * EPOCHS_PER_FRAME + 1) * SECONDS_PER_SLOT chain.sleep(frame_start_with_offset - time) chain.mine(1) (nextRefSlot, _) = consensus_contract.getCurrentFrame() From 8dc8c50477ab86c164ebb2a0920cd1d4957f1536 Mon Sep 17 00:00:00 2001 From: maksim Date: Tue, 15 Oct 2024 13:40:39 +0200 Subject: [PATCH 161/220] tests: update easy track target validators limit factory test --- tests/regression/test_easy_track_factories.py | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tests/regression/test_easy_track_factories.py b/tests/regression/test_easy_track_factories.py index 72b476168..2098984a9 100644 --- a/tests/regression/test_easy_track_factories.py +++ b/tests/regression/test_easy_track_factories.py @@ -93,8 +93,8 @@ def set_node_operator_reward_addresses(operators, stranger): def update_target_validators_limits(operators, stranger): calldata = _encode_calldata( - ["(uint256,bool,uint256)[]"], - [[(no["id"], no["is_target_limit_active"], no["target_limit"]) for no in operators]], + ["(uint256,uint256,uint256)[]"], + [[(no["id"], no["target_limit_mode"], no["target_limit"]) for no in operators]], ) factory = interface.UpdateTargetValidatorLimits(EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY) @@ -293,25 +293,34 @@ def test_update_target_validator_limits(stranger): [ { "id": 1, - "is_target_limit_active": True, + "target_limit_mode": 0, "target_limit": 800, }, { "id": 2, - "is_target_limit_active": False, + "target_limit_mode": 1, "target_limit": 900, }, + { + "id": 3, + "target_limit_mode": 2, + "target_limit": 1000, + }, ], stranger, ) summary_1 = contracts.simple_dvt.getNodeOperatorSummary(1) - assert summary_1["targetLimitMode"] == 1 - assert summary_1["targetValidatorsCount"] == 800 + assert summary_1["targetLimitMode"] == 0 + assert summary_1["targetValidatorsCount"] == 0 # should be 0 because targetLimitMode is 0 summary_2 = contracts.simple_dvt.getNodeOperatorSummary(2) - assert summary_2["targetLimitMode"] == 0 - assert summary_2["targetValidatorsCount"] == 0 # should be 0 because targetLimitMode is 0 + assert summary_2["targetLimitMode"] == 1 + assert summary_2["targetValidatorsCount"] == 900 + + summary_3 = contracts.simple_dvt.getNodeOperatorSummary(3) + assert summary_3["targetLimitMode"] == 2 + assert summary_3["targetValidatorsCount"] == 1000 def test_transfer_node_operator_manager(stranger): From f12587aa9a11bd478624dfe82f901e355016951b Mon Sep 17 00:00:00 2001 From: skhomuti Date: Wed, 16 Oct 2024 14:02:23 +0500 Subject: [PATCH 162/220] add new csm checks revert network config changes fix merge mistakes --- network-config.yaml | 162 ------------------ ...accounting_oracle_extra_data_full_items.py | 2 +- tests/regression/test_csm.py | 7 +- tests/snapshot/test_first_slots.py | 9 + utils/test/csm_helpers.py | 105 +++++++++++- 5 files changed, 119 insertions(+), 166 deletions(-) diff --git a/network-config.yaml b/network-config.yaml index 9e5ff513e..3d3472a4d 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -82,165 +82,3 @@ development: timeout: 360 # https://github.com/mds1/multicall#multicall2-contract-addresses multicall2: "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696" - - - -development: - - name: Anvil - id: anvil - cmd: anvil - host: http://127.0.0.1 - cmd_settings: - port: 8545 - - name: Anvil (Mainnet Fork) - id: anvil-fork - cmd: anvil - host: http://127.0.0.1 - cmd_settings: - fork: mainnet - port: 8545 - - name: Anvil (Holesky Fork) - id: anvil-holesky-fork - cmd: anvil - host: http://127.0.0.1 - cmd_settings: - fork: holesky - port: 8545 - - name: Ganache-CLI - id: development - cmd: ganache-cli - host: http://127.0.0.1 - cmd_settings: - port: 8545 - gas_limit: 12000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - - name: Geth Dev - id: geth-dev - cmd: ethnode - host: http://127.0.0.1 - cmd_settings: - port: 8545 - - name: Hardhat - id: hardhat - cmd: npx hardhat node - host: http://localhost - cmd_settings: - port: 8545 - - name: Hardhat (Mainnet Fork) - id: hardhat-fork - cmd: npx hardhat node - host: http://localhost - timeout: 120 - cmd_settings: - port: 8545 - fork: mainnet - - name: Ganache-CLI (Mainnet Fork) - id: mainnet-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 12000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: mainnet - - name: Ganache-CLI (BSC-Mainnet Fork) - id: bsc-main-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 12000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: bsc-main - - name: Ganache-CLI (FTM-Mainnet Fork) - id: ftm-main-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 12000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: ftm-main - - name: Ganache-CLI (Polygon-Mainnet Fork) - id: polygon-main-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 20000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: polygon-main - - name: Ganache-CLI (Avax-Mainnet Fork) - id: avax-main-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 20000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: avax-main - - name: Ganache-CLI (Aurora-Mainnet Fork) - id: aurora-main-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 20000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: aurora-main - - name: Ganache-CLI (Gnosis-Mainnet Fork) - id: gnosis-main-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 20000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: gnosis-main - - name: Ganache-CLI (zkEVM-Mainnet Fork) - id: zkevm-main-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 20000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: zkevm-main - - name: Ganache-CLI Base-Mainnet Fork) - id: base-main-fork - cmd: ganache-cli - host: http://127.0.0.1 - timeout: 120 - cmd_settings: - port: 8545 - gas_limit: 20000000 - accounts: 10 - evm_version: istanbul - mnemonic: brownie - fork: base-main diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 40e4fb665..7ae4e61be 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -341,7 +341,7 @@ def fill_csm_operators_with_keys(target_operators_count, keys_count): def fill_nor_with_old_and_new_operators( - nor, voting_eoa, evm_script_executor_eoa, new_keys_per_operator, nor_stuck_items, nor_exited_items, max_node_operators_per_item + nor, voting_eoa, evm_script_executor_eoa, new_keys_per_operator, max_node_operators_per_item ) -> tuple[int, int]: contracts.acl.grantPermission( contracts.voting, diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py index 158cce008..093737d0b 100644 --- a/tests/regression/test_csm.py +++ b/tests/regression/test_csm.py @@ -8,7 +8,7 @@ ) from utils.dsm import UnvetArgs, to_bytes, set_single_guardian from utils.evm_script import encode_error -from utils.test.csm_helpers import csm_add_node_operator, get_ea_member, csm_upload_keys +from utils.test.csm_helpers import csm_add_node_operator, get_ea_member, csm_upload_keys, get_ea_members from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.helpers import ETH from utils.test.oracle_report_helpers import ( @@ -95,6 +95,11 @@ def distribute_reward_tree(deposits_to_csm, fee_oracle, fee_distributor, node_op return tree +@pytest.mark.parametrize("address, proof", get_ea_members()) +def test_add_ea_node_operator(csm, accounting, address, proof): + csm_add_node_operator(csm, accounting, address, proof) + + @pytest.mark.usefixtures("pause_modules") def test_deposit(node_operator, csm): (_, _, depositable_validators_count) = csm.getStakingModuleSummary() diff --git a/tests/snapshot/test_first_slots.py b/tests/snapshot/test_first_slots.py index caa3c44f1..111350ca8 100644 --- a/tests/snapshot/test_first_slots.py +++ b/tests/snapshot/test_first_slots.py @@ -62,6 +62,8 @@ def skip_slots() -> Sequence[tuple[str, int]]: # new EasyTrack factory for CSM (EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY) # evmScriptFactories array (contracts.easy_track.address, 5), + # Set initial epoch for CSM hash consensus + (contracts.csm_hash_consensus.address, 0) ] @@ -118,6 +120,13 @@ def _snap(): contracts.kernel, contracts.easy_track, contracts.wsteth, + contracts.csm, + contracts.cs_early_adoption, + contracts.cs_accounting, + contracts.cs_fee_distributor, + contracts.cs_fee_oracle, + contracts.csm_hash_consensus, + contracts.cs_verifier, ): res |= _get_slots(contract, block) diff --git a/utils/test/csm_helpers.py b/utils/test/csm_helpers.py index 7924973f9..0cbc86e6c 100644 --- a/utils/test/csm_helpers.py +++ b/utils/test/csm_helpers.py @@ -29,6 +29,107 @@ def get_ea_member(): return address, proof +def get_ea_members(): + """Each ea member from different source""" + return (( + "0x113e5bA177D3021E4515e847bc4779B074AA0813", [ # good performer + "0xb3f1d62e731a0ac46f103f3423265baaae773036410890c1ee4bc4ba4a5b6806", + "0xdd218546f8029d89f8bb325d50e9a272543ac9642e88d60c6d5b0f1d11db14ea", + "0x82a14915d66df3004c15749f90a53606faaa8adcf890ef9159974a470df16a1f", + "0x9f7ee78a4e733ab2715190ae5481a1456b81b3d5b65a05cd070bcf95fe7a7c92", + "0x68431bdd53ada7d0fcbc0eeae8a7e0f614cbd3da6b54b16214bfedc9e42ea753", + "0x2006bffe956465add92037dd50b5001f7bfdc9ed531fb40b9bbcdff3586ffb63", + "0xbf0015b0b477df4cd5a81eda856a20d65f1a631f033eeb4d630fbebf962a8310", + "0x03c02b7b15ef3c91ae99e86c4c3b1eee48c776e38ffff1a99dcbe4f78942679f", + "0xacbd1f9b565d87a3156b972c1a860a71b5365992f503821166f2c11f591748ec", + "0x8ac7d39a7d9d96d17f5b42f8ef026c44ebb17bd62c995f12e3124b5ca4bfc5e7", + "0x582edbfcd0fb5f0a95caca952bdb943a8cd008c4d114c586e4e03c839bc7c7cd", + "0x772f2c70f39b9a6848799e13c16fe05bdfd1eded3c2b588834bf751b79a9fce5", + "0x3f53e44db24145c061bbbf7d1df796a0ab059b7125c9c2cacf7064bc3904c9d1", + "0x617a04e701d0b1c8e0e96c278ba4caf00e2d787e4287e52fcc4b5f248d89c2b3" + ]), + ("0x6D08b74BD14b2D6Deb468BA31D578a002D0AdDE8", [ # Galxe point holder + "0x6184b17c37f752a58be2c14d26abf9220efff1349fb5c561d9b688b798237d13", + "0xe2d16f320a6de8ef9c8fdca825bad92bb3df1da7995b035d4c0ce2a68cbd3e2a", + "0x35f55c85e9331c8767bf00735389eebc9ba335f52922809cc9cf8d8487646d27", + "0x6442dd1037d0faced9476b99c7f93987326845cd36114be02abebf734759e8a9", + "0xc7f4e2bc84d3a89a6046c9feae416160dad7b28a6209b1e3dff004a3d2b4d0de", + "0xc69995256422fbd2478a7bb8201c777383493e4c1a2fc6a45620341d8108103d", + "0xd703c9506f78ffe85059902bf94a1da7d0efa195424ee10d436af20867700d7c", + "0xfa6b80e968a2f48fc65a45e6763f5a0d470f7640f75edf648d001cb46acefe3c", + "0x9950a0f220017fcd05a338574cbc289a3c00de804ca8d10867a177afd673c347", + "0x83389a6b368766d86b6d57720596f25ff3aeccd4ad21a3b683dbbd231755a2df", + "0x2980e52feb24b69169c73a9618107b58ae5bea120649a045aba137b07e822172", + "0xdbaa84b6f34f08ec11a23797a3497898e75dec4e99bf42d63e7cbfee0dee67d6", + "0xc4556dc19f0330ccc6c929b09a965e05c360d32a5c71c3f64b4123fda973b8dd", + "0x617a04e701d0b1c8e0e96c278ba4caf00e2d787e4287e52fcc4b5f248d89c2b3" + ]), + ("0xe95fb9768cef2893445bc02e7056dead0c32fe6a", [ # dappnode buyer + "0x6fdf504e61ce21367058bc13a34c21f94a4320e29b75c632aa371dd228f2595e", + "0xeeda87c6ce2ef88e9748f7987a64a7147a93be2297f62f44c75f38e5c5756111", + "0x852b5fdd3cf28c632af3270443231205b4d5fa8186b6e241e4f8d3414bfbb540", + "0xa4d359ba49c62fe93c99b49ac4453cf544252e6bf1a42fababa321bb23850163", + "0x8a9297667d1dbe4f17916ff6bc052e58790a3df7703b22baac3f4d224c06a444", + "0x696335ac8a25acf05c2b7b85bd97e0473219f8fff3bc89f49601ba6084f54e51", + "0x6aa7a7a69448a2170b3dc9f6f6227cd0926dd71962e4c15e63448a984369c7a4", + "0x5f87b1e6bfecfd3440114bd9829647532aad1328699af183aeb490d1406003cd", + "0x9d117f35be949e6db5e479949f91cb0710ea3e85be2a58deed5a0b4c05763fe3", + "0x70d5df1f59c0f5fd1667e832f91b8e389adc70f69a520a9f9ca333861bdb27e2", + "0x398e90a61a92850edce556da82fbb16b5f520bcf3fb3c1a5d7cdc6a1baf4883c", + "0xdbaa84b6f34f08ec11a23797a3497898e75dec4e99bf42d63e7cbfee0dee67d6", + "0xc4556dc19f0330ccc6c929b09a965e05c360d32a5c71c3f64b4123fda973b8dd", + "0x617a04e701d0b1c8e0e96c278ba4caf00e2d787e4287e52fcc4b5f248d89c2b3" + ]), + ("0x024813b4972428003c725ea756348dcd79b826e6", [ # obol teche credentials + "0xfc49117ff5d49126e2ed0ee2a6229678604428fc175670aaf6dfcacfba55c414", + "0xa9011da71acb5f3c61c0cc80f5c8b89f916345efb9c149ead010aac852dfbac3", + "0xa0af25f19dde818bb362aae34d967c6d141cfe4b2666a9aeef5fb03cf705ab1b", + "0xb8a34c5bdc302c3944e1f1919f304aa25168e0db81b7e2b67c6afe8a7fa8cc46", + "0x6c209589c3c08d2b8441263874648617f70ebfd255d513840aa191284b5815a9", + "0x45493cc5f6e07014c06f4fe700bc91cedbe7947bdae3d3bdf960ae67abab3adf", + "0xa6df3cbb3e9113c1c429e842c8999b3597d1b6b55c9c979c2703e995b0f762c6", + "0x9e70b4cb13a9517ad1a4fe4920b02abd9eeab2236b9a541e20beaee5557ad7fd", + "0x0a9dc8737db2646bbfc1539e073b563f203e9bfed2aabacfcd03d9d16e8f9739", + "0x2f362f8032842941fe910be787723b082ab7a21effb5cd38022b36c75a103013", + "0x6a5e8cf1bacfe83bee183d9ed803f679d8714103a8106301ad9e355f7790e901", + "0xd001326ce1fa4bfc303be10f953c87ad779c22268ea03d357da5d8e26659e50b", + "0xd597d21fed5e65b2a6de1c6fe70dfdb2df43ab5495a5c0a01c915e60c14c6edb", + "0xf99292f2fccc3f4fa8cef73512bd5f21a46214d922dfed8e8a65f763c13dfb72" + ]), + ("0xe3a2417f8eaafb93a93dc896724e20d0bc1a1feb", [ # rated + "0x2faac9fec99b1a1d464422f5cc64c153514da1d3a438362ef7f1aaa5f585cf65", + "0xf17a0bdf45def725c1ad7bf6c457d4c749705f02ff4282c6739e54dc8965340b", + "0xa0530504a2c0e61ab5de781f0ee4467097595b7a9815b9b2371e33daf920e25c", + "0x1d95475075f06c85ba13b81f01891bde5cf0af4df6f2693b15586884b4a3fac7", + "0x4a8ebe10d4e6f7bb1cadf1e54b58471a6933a62fd7fd6b4750c645f87347c8bd", + "0x96f7f6c9f3b8c3c45392e1598c4ee9ff2aa0eb655bb428c3977e939a8c2cacf5", + "0x404ba635ed5cce8cbc77c4b0eb581c8383e52a7be1507d9fbb053d86fe132fd4", + "0xa680f8f19b75770eee3435719f5731dccd057b968fabd81b40528a9b689a7b6c", + "0x78fe6adcb23cf69e7533e4a3d0558fdc6f0bf13384e85c7679b6d054b05b34ed", + "0xbab879d3c26f5d5e3816a4ce99f35a6ac8139c8df8053608bea4a76951b17e0d", + "0x15b1fc08779715ad26f61b07d0665a82f118104391b56863bd54e6bbe3ec0ff0", + "0xbe7a61521ebadab96f18fdce4dbcfed777f7799c1a02400052ee9dd838ff1ad4", + "0x5894e79a333e76f3e367a65aaad4cc2ca21650c4a532ce89b28009b0d35ca075", + "0xd597d21fed5e65b2a6de1c6fe70dfdb2df43ab5495a5c0a01c915e60c14c6edb", + "0xf99292f2fccc3f4fa8cef73512bd5f21a46214d922dfed8e8a65f763c13dfb72" + ]), + ("0x61ad82d4466437d4cc250a0ceffbcbd7e07b8f96", [ # stake cat + "0xc863e03646d118cf51af3581cacc457f166134a78b3f4253b219e7f694becc50", + "0x52b3bb9a9105a40e8270cd7e6687f3b010213bd9297748d90b7f90dad779defd", + "0x82e0aec8e35aa0c9b8732a77dc5470b13f3d9d36870acec8568ce73807674a15", + "0x096a86c63fccf92230d8d445d7df591d20f9d71ed5c77141e4bb85a47acbb2e3", + "0x4b875dfece281e9d8ab00c0b8544fa7431dc99661c44e0e6cbaad66f942e5c62", + "0x0590fd2e84b7f5a152881a0d17a6fe0732be6ffd020ada4e91693f8e94696cd8", + "0x1f99300883319c93920319ed5159329a98f2efc356165d9587c316abd6d4cbac", + "0x516c84f2139897f30531bd6e08f3372c0a06bdccd9f17ce91bd2565c79b1afca", + "0x5b698237e78d7b2ef3227a5bc652d030bba9bfa8f21aec555eee0b4f65a24b40", + "0x0a125fd7e859f5e8a67214923c80caaa3e48da3ea985ab0d346ed36a0a92989a", + "0xefb4a879db517af0fb7e4f0731a12d8360bc6a155fcfc7546ace79b55cdafa52", + "0xd2af30f01b69d3f2d1d94e5b401418ffa90b566b1450d7b3310a097701ac694a", + "0x769a53742322902c2080251b628f262577d620d70831c142a59b77910c464a63", + "0xf99292f2fccc3f4fa8cef73512bd5f21a46214d922dfed8e8a65f763c13dfb72"]) + ) + def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5, curve_id=0): pubkeys_batch = random_pubkeys_batch(keys_count) signatures_batch = random_signatures_batch(keys_count) @@ -48,11 +149,11 @@ def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5, c return csm.getNodeOperatorsCount() - 1 - def csm_upload_keys(csm, accounting, no_id, keys_count=5): manager_address = csm.getNodeOperator(no_id)["managerAddress"] pubkeys_batch = random_pubkeys_batch(keys_count) signatures_batch = random_signatures_batch(keys_count) csm.addValidatorKeysETH(no_id, keys_count, pubkeys_batch, signatures_batch, - {"from": manager_address, "value": accounting.getRequiredBondForNextKeys(no_id, keys_count)} + {"from": manager_address, + "value": accounting.getRequiredBondForNextKeys(no_id, keys_count)} ) From 0c2d26eb970ac0ce88f6800034b4f4ad1b0da80d Mon Sep 17 00:00:00 2001 From: skhomuti Date: Wed, 16 Oct 2024 15:15:28 +0500 Subject: [PATCH 163/220] add missed csm tests --- tests/acceptance/test_csm.py | 4 +-- tests/regression/test_csm.py | 49 +++++++++++++++++++++++++++++++++++- tests/test_upgrade_sr_v2.py | 2 ++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/tests/acceptance/test_csm.py b/tests/acceptance/test_csm.py index 774d16d41..90cf13dc8 100644 --- a/tests/acceptance/test_csm.py +++ b/tests/acceptance/test_csm.py @@ -79,8 +79,8 @@ def test_init_state(self, csm): assert csm.LIDO_LOCATOR() == LIDO_LOCATOR assert csm.accounting() == CS_ACCOUNTING_ADDRESS - assert not csm.isPaused(); - assert not csm.publicRelease(); + assert not csm.isPaused() + assert not csm.publicRelease() class TestAccounting: diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py index 093737d0b..897c9cd36 100644 --- a/tests/regression/test_csm.py +++ b/tests/regression/test_csm.py @@ -1,7 +1,8 @@ import pytest -from brownie import reverts, web3 +from brownie import reverts, web3, ZERO_ADDRESS +from utils.balance import set_balance_in_wei from utils.config import ( contracts, ContractsLazyLoader, @@ -166,6 +167,7 @@ def test_csm_report_exited(csm, node_operator, extra_data_service): no = csm.getNodeOperator(node_operator) assert no["totalExitedKeys"] == exited_keys + @pytest.mark.usefixtures("deposits_to_csm") def test_csm_report_stuck(csm, node_operator, extra_data_service): stuck_keys = 5 @@ -262,6 +264,51 @@ def test_csm_decrease_vetted_keys(csm, node_operator, stranger): assert no["totalVettedKeys"] == 1 +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_penalize_node_operator(csm, accounting, node_operator, helpers): + bond_before = accounting.getBond(node_operator) + tx = csm.submitInitialSlashing(node_operator, 0, {"from": contracts.cs_verifier}) + assert "StETHBurnRequested" in tx.events + assert accounting.getBond(node_operator) < bond_before + + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_deposit_eth(csm, accounting, node_operator): + manager_address = csm.getNodeOperator(node_operator)["managerAddress"] + set_balance_in_wei(manager_address, ETH(2)) + + bond_before = accounting.getBond(node_operator) + csm.depositETH(node_operator, {"from": manager_address, "value": ETH(1)}) + assert accounting.getBond(node_operator) > bond_before + + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_deposit_steth(csm, accounting, node_operator): + manager_address = csm.getNodeOperator(node_operator)["managerAddress"] + set_balance_in_wei(manager_address, ETH(2)) + + bond_before = accounting.getBond(node_operator) + contracts.lido.submit(ZERO_ADDRESS, {"from": manager_address, "value": ETH(1.5)}) + contracts.lido.approve(accounting, ETH(2), {"from": manager_address}) + + csm.depositStETH(node_operator, ETH(1), (0, 0, 0, 0, 0), {"from": manager_address}) + assert accounting.getBond(node_operator) > bond_before + + +@pytest.mark.usefixtures("deposits_to_csm") +def test_csm_deposit_wsteth(csm, accounting, node_operator): + manager_address = csm.getNodeOperator(node_operator)["managerAddress"] + set_balance_in_wei(manager_address, ETH(2)) + contracts.lido.submit(ZERO_ADDRESS, {"from": manager_address, "value": ETH(1.5)}) + contracts.lido.approve(contracts.wsteth, ETH(1.5), {"from": manager_address}) + contracts.wsteth.wrap(ETH(1.5), {"from": manager_address}) + contracts.wsteth.approve(accounting, contracts.wsteth.balanceOf(manager_address), {"from": manager_address}) + + bond_before = accounting.getBond(node_operator) + csm.depositWstETH(node_operator, contracts.wsteth.balanceOf(manager_address), (0, 0, 0, 0, 0), {"from": manager_address}) + assert accounting.getBond(node_operator) > bond_before + + @pytest.mark.usefixtures("deposits_to_csm") def test_csm_claim_rewards_steth(csm, distribute_reward_tree, node_operator, fee_distributor): tree = distribute_reward_tree.tree diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index c22ca9b27..f27df9b1b 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -255,6 +255,7 @@ def test_vote( assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 assert not burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) assert not csm.hasRole(RESUME_ROLE, AGENT) + assert csm.isPaused() # START VOTE if len(vote_ids_from_env) > 0: @@ -290,6 +291,7 @@ def test_vote( assert burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) assert not csm.hasRole(RESUME_ROLE, AGENT) + assert not csm.isPaused() assert csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH From 40eb32ccb00f96fd017fd93ae60eb5cb95644eaa Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 16 Oct 2024 12:22:14 +0200 Subject: [PATCH 164/220] test: fix event parsing --- utils/test/node_operators_helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/test/node_operators_helpers.py b/utils/test/node_operators_helpers.py index f4a8c1505..ecba883de 100644 --- a/utils/test/node_operators_helpers.py +++ b/utils/test/node_operators_helpers.py @@ -85,10 +85,10 @@ def encode_event_arguments(event_signature: str, *event_args): def get_event_arg_types(event_signature: str): # extract args clause with brackets, i.e. (uin256,address) - event_args = next(iter(re.findall(r"(.*)", event_signature)), None) + event_args = next(iter(re.findall(r"\(([^)]+)\)", event_signature)), None) assert event_args is not None, f'Cant extract arguments from event signature "{event_signature}"' - return event_args.strip("()").split(",") + return event_args.split(",") def get_event_log(tx: network.transaction.TransactionReceipt, event_signature: str): From afd96d2ab3b2737f4b518f98bfe640bcb4b588b8 Mon Sep 17 00:00:00 2001 From: VP Date: Wed, 16 Oct 2024 12:39:50 +0200 Subject: [PATCH 165/220] test: remove reporting for zero exited validators value --- tests/regression/test_neg_rebase_sanity_checks.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/regression/test_neg_rebase_sanity_checks.py b/tests/regression/test_neg_rebase_sanity_checks.py index 92840cda6..6e0d86799 100644 --- a/tests/regression/test_neg_rebase_sanity_checks.py +++ b/tests/regression/test_neg_rebase_sanity_checks.py @@ -82,7 +82,6 @@ def test_blocked_huge_negative_rebase(oracle_report_sanity_checker): max_cl_balance = (INITIAL_SLASHING_AMOUNT_PWEI + INACTIVITY_PENALTIES_AMOUNT_PWEI) * ONE_PWEI * cl_validators error_cl_decrease = cl_balance // 10 # 10% of current balance will lead to error - print("max_cl_balance", max_cl_balance) with reverts(encode_error("IncorrectCLBalanceDecrease(uint256, uint256)", [error_cl_decrease, max_cl_balance])): oracle_report(cl_diff=-error_cl_decrease, exclude_vaults_balances=True, silent=True) @@ -108,6 +107,9 @@ def exited_validators_count(): ids = contracts.staking_router.getStakingModuleIds() exited = {} for id in ids: - exited[id] = contracts.staking_router.getStakingModule(id)["exitedValidatorsCount"] + exited_validators = contracts.staking_router.getStakingModule(id)["exitedValidatorsCount"] + # It's possible to report only non-zero values for exited validators + if exited_validators > 0: + exited[id] = exited_validators return exited From 298b1173139e26209ddcbe2452017d87c22359a7 Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 16 Oct 2024 12:58:43 +0200 Subject: [PATCH 166/220] upgrade hardfork version to shanghai --- network-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network-config.yaml b/network-config.yaml index 3d3472a4d..ac6e92448 100644 --- a/network-config.yaml +++ b/network-config.yaml @@ -19,7 +19,7 @@ development: gas_limit: 30000000 mnemonic: brownie port: 8545 - evm_version: london + evm_version: shanghai host: http://127.0.0.1 id: mainnet-fork name: Ganache-CLI (Mainnet Fork) From 57095b910c0eaae8f0a09a90fc17907f87e768db Mon Sep 17 00:00:00 2001 From: skhomuti Date: Wed, 16 Oct 2024 16:29:36 +0500 Subject: [PATCH 167/220] fix test_stake_distribution --- tests/regression/test_staking_router_stake_distribution.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/regression/test_staking_router_stake_distribution.py b/tests/regression/test_staking_router_stake_distribution.py index f827a7221..53b7e0579 100644 --- a/tests/regression/test_staking_router_stake_distribution.py +++ b/tests/regression/test_staking_router_stake_distribution.py @@ -136,8 +136,8 @@ def test_stake_distribution(stranger): # perform deposits to the modules for module in modules.values(): - assert module.allocated_keys > 0 - contracts.lido.deposit(module.allocated_keys, module.id, "0x", {"from": contracts.deposit_security_module}) + if module.allocated_keys > 0: + contracts.lido.deposit(module.allocated_keys, module.id, "0x", {"from": contracts.deposit_security_module}) # check that the new active keys in the modules match the expected values module_digests_after_deposit = contracts.staking_router.getAllStakingModuleDigests() From 7a2df94c2af96852e526ff1c07a99ea3a3277f35 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Wed, 16 Oct 2024 17:43:46 +0500 Subject: [PATCH 168/220] fix incorrect keys count calculation --- .../regression/test_accounting_oracle_extra_data_full_items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 7ae4e61be..61d151d64 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -330,7 +330,7 @@ def fill_csm_operators_with_keys(target_operators_count, keys_count): for no_id in range(0, csm_node_operators_before): depositable_keys = contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] if depositable_keys < keys_count: - csm_upload_keys(contracts.csm, contracts.cs_accounting, no_id, depositable_keys - keys_count) + csm_upload_keys(contracts.csm, contracts.cs_accounting, no_id, keys_count - depositable_keys) assert contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] == keys_count while csm_node_operators_before + added_operators_count < target_operators_count: node_operator = f"0xbb{str(added_operators_count).zfill(38)}" From 100faa92d056d63215e6e35c49afa20c475021c6 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Thu, 17 Oct 2024 12:16:45 +0400 Subject: [PATCH 169/220] doc: sr+csm voting description --- scripts/upgrade_sr_v2.py | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 6f62c6cb8..e6b239d32 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -118,36 +118,16 @@ CS_ORACLE_INITIAL_EPOCH = 326715 description = """ -Proposal to support SR 2.0 and CSM Module +Release the Community Staking Module (CSM) for permissionless staking and upgrade the Staking Router to ensure compatibility with CSM and future modules, improving system efficiency. A detailed action plan can be found [on the research forum](https://research.lido.fi/t/staking-router-community-staking-module-upgrade-announcement/8612/6). -1. Update Locator implementation -2. Revoke pause role from old Deposit Security Module -3. Revoke resume role from old Deposit Security Module -4. Grant unvetting role to new Deposit Security Module -5. Update Staking Router implementation -6. Call finalize upgrade on Staking Router -7. Publish new Node Operators Registry implementation in Node Operators Registry app APM repo -8. Update Node Operators Registry implementation -9. Finalize Node Operators Registry upgrade -10. Publish new SimpleDVT implementation in SimpleDVT app APM repo -11. Update SimpleDVT implementation -12. Finalize SimpleDVT upgrade -13. Update Accounting Oracle implementation -14. Finalize Accounting Oracle upgrade and update consensus version -15. Grant manage consensus role to Aragon Agent -16. Update Validator Exit Bus Oracle consensus version -17. Revoke manage consensus role from Aragon Agent -18. Remove old UpdateTargetValidatorLimits for SimpleDVT factory from EasyTrack -19. Add new UpdateTargetValidatorLimits for SimpleDVT factory to EasyTrack +1. **Staking Router and related contracts upgrade** following the DAO-approved [LIP-25: Staking Router 2.0](https://snapshot.org/#/lido-snapshot.eth/proposal/0xffb4042d3bfceef33c66f78c092a76fa8e1db198559d93798cc9db3fb4d722e7) and [LIP-23: Negative rebase sanity check with a pluggable second opinion](https://snapshot.org/#/lido-snapshot.eth/proposal/0xa44f6a4dba07d7e24b0e4180025f7a9db6251046daa74d2a8fae84de0d9ce21e) designs. + +2. **Add Community Staking Module** to the Staking Router. CSM follows the [approved LIP-26 design and Mainnet Release Setup](https://snapshot.org/#/lido-snapshot.eth/proposal/0xd0d7bfd68f2241524dbb14ae6fe0e8414b9fe3e0dcfc50641a8d28f0067d6693). -Community Staking Module -20. Add Community Staking Module to Staking Router -21. Grant request burn role to CSAccounting -22. Grant resume role to Aragon Agent -23. Resume Community Staking Module -24. Revoke resume role from Aragon Agent -25. Update initial epoch on CSHashConsensus -26. Add CSMSettleElStealingPenalty factory to EasyTrack +**Audits:** +[Staking Router 2.0 upgrade](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Staking%20Router%20v2%20Report%2010-24.pdf), [CSM](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Community%20Staking%20Module%20Report%2010-24.pdf) both with deployment verification by Ackee Blockchain; [Staking Router 2.0 & CSM](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20CSM%20Security%20Audit%20Report%2010-24.pdf), [Lido Oracle](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Oracle%20Security%20Audit%20Report%2010-24.pdf) (incl. CSM Oracle) by Mixbytes; + +The AccountingOracle (negative rebase parameters, pluggable second opinion) was part of Staking Router 2.0 upgrade audits and also audited separately: [Mixbytes report](https://github.com/lidofinance/audits/blob/main/Lido%20Sanity%20Checker%20Security%20Audit%20Report.pdf) and [ChainSecurity report](https://github.com/lidofinance/audits/blob/main/ChainSecurity%20Code%20Assessment%20of%20LIP-23%20Negative%20Rebase%20Checks%20Smart%20Contracts%2006-24.pdf). """ From 83ab26af2a662a81801af9922a47445e6b8462a7 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Thu, 17 Oct 2024 14:20:23 +0500 Subject: [PATCH 170/220] add more eth to local deployer --- utils/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/config.py b/utils/config.py index 4dae172ea..767e86afc 100644 --- a/utils/config.py +++ b/utils/config.py @@ -74,9 +74,9 @@ def local_deployer() -> LocalAccount: deployer = accounts[4] agent = accounts.at(AGENT, force=True) - if web3.eth.get_balance(agent.address) < 10 ** 18: + if web3.eth.get_balance(agent.address) < 10 * 10 ** 18: from utils.balance import set_balance - set_balance(agent.address, 1) + set_balance(agent.address, 10) interface.MiniMeToken(LDO_TOKEN).transfer(deployer, 10**18, {"from": agent}) return deployer From 099c57be88de5b89dca80d95231313252faeaf57 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 17 Oct 2024 18:46:41 +0400 Subject: [PATCH 171/220] fix: resolve todo, cehck sr version after enact --- tests/test_upgrade_sr_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index f27df9b1b..36fc01311 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -264,7 +264,6 @@ def test_vote( tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS} vote_id, _ = start_vote(tx_params, silent=True) - # TODO: do we need instead use contracts.voting that read address from config? voting = get_voting() vote_tx = helpers.execute_vote(accounts, vote_id, voting) @@ -281,6 +280,7 @@ def test_vote( check_ossifiable_proxy_impl(sr_proxy, NEW_STAKING_ROUTER_IMPL) check_module_after_vote(CURATED_MODULE_AFTER_VOTE) check_module_after_vote(SDVT_MODULE_AFTER_VOTE) + assert staking_router.getContractVersion() == 2 # AO check_ossifiable_proxy_impl(ao_proxy, NEW_ACCOUNTING_ORACLE_IMPL) From 159f2839b0d34d62af708f67d5ec516108b73fbe Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Thu, 17 Oct 2024 18:54:35 +0400 Subject: [PATCH 172/220] fix: error descr --- tests/test_upgrade_sr_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index 36fc01311..944ac1913 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -524,7 +524,7 @@ def validate_upgrade_events(events: EventDict, implementation: str): _events_chain = ["LogScriptCall", "LogScriptCall", "Upgraded", "ScriptResult"] validate_events_chain([e.name for e in events], _events_chain) assert events.count("Upgraded") == 1 - assert events["Upgraded"]["implementation"] == implementation, "Wrong withdrawal vault proxy implementation" + assert events["Upgraded"]["implementation"] == implementation, "Wrong proxy implementation address" def validate_dsm_roles_events(events: list[EventDict]): From 76849d303cac16b84a3dba1f3e3e199c1a270fdb Mon Sep 17 00:00:00 2001 From: maksim Date: Thu, 17 Oct 2024 17:47:09 +0200 Subject: [PATCH 173/220] test: add pause deposits tests for dsm --- tests/regression/test_dsm_pause_deposits.py | 96 +++++++++++++++++++++ utils/dsm.py | 15 ++++ 2 files changed, 111 insertions(+) create mode 100644 tests/regression/test_dsm_pause_deposits.py diff --git a/tests/regression/test_dsm_pause_deposits.py b/tests/regression/test_dsm_pause_deposits.py new file mode 100644 index 000000000..390e7b964 --- /dev/null +++ b/tests/regression/test_dsm_pause_deposits.py @@ -0,0 +1,96 @@ +import pytest +from brownie import accounts, chain, interface, reverts +from utils.config import ( + contracts +) +from utils.dsm import DSMPauseDepositsMessage, set_single_guardian +from utils.evm_script import encode_error + +EMPTY_SIGNATURE = (0, 0) + +@pytest.fixture(scope="module") +def dsm() -> interface.DepositSecurityModule: + return contracts.deposit_security_module + +@pytest.fixture +def agent(accounts): + return accounts.at(contracts.agent.address, force=True) + +def generate_pause_deposit_sig(dsm, block_number, private_key): + DSMPauseDepositsMessage.set_message_prefix(dsm.PAUSE_MESSAGE_PREFIX()) + + valid_pause_deposits_message = DSMPauseDepositsMessage(block_number) + (compact_r, compact_vs) = valid_pause_deposits_message.sign(private_key) + + return (compact_r, compact_vs) + +def pause_deposits(dsm, pauser, block_number, sig, guardian): + assert dsm.isDepositsPaused() == False + + pause_deposit_tx = dsm.pauseDeposits( + block_number, + sig, + {"from": pauser}, + ) + + deposits_paused_event = pause_deposit_tx.events["DepositsPaused"] + + assert len(deposits_paused_event) == 1 + assert deposits_paused_event[0]["guardian"] == guardian + assert dsm.isDepositsPaused() == True + + return pause_deposit_tx + +def owner_unpause_deposits(dsm): + assert dsm.isDepositsPaused() == True + owner = dsm.getOwner() + + unpause_deposit_tx = dsm.unpauseDeposits( + {"from": owner}, + ) + + deposits_unpaused_event = unpause_deposit_tx.events["DepositsUnpaused"] + assert len(deposits_unpaused_event) == 1 + assert dsm.isDepositsPaused() == False + +def test_dsm_pause_by_guardian_happy_path(dsm): + guardian = dsm.getGuardians()[0] + pause_deposits(dsm, guardian, chain.height, EMPTY_SIGNATURE, guardian) + owner_unpause_deposits(dsm) + +def test_dsm_pause_by_stranger_with_guardian_sign_happy_path(dsm, stranger, agent): + new_guardian_private_key="0x516b8a7d9290502f5661da81f0cf43893e3d19cb9aea3c426cfb36e8186e9c09" + new_guardian = accounts.add(private_key=new_guardian_private_key) + + set_single_guardian(dsm, agent, new_guardian) + + block_number=chain.height + sig = generate_pause_deposit_sig(dsm, block_number, new_guardian_private_key) + + pause_deposits(dsm, stranger, block_number, sig, new_guardian) + owner_unpause_deposits(dsm) + +def test_dsm_pause_deposits_with_expired_block_number(dsm, agent): + block_number=chain.height - dsm.getPauseIntentValidityPeriodBlocks() - 1 + guardian = dsm.getGuardians()[0] + + with reverts(encode_error("PauseIntentExpired()")): + dsm.pauseDeposits(block_number, EMPTY_SIGNATURE, {"from": guardian}) + +def test_dsm_pause_by_stranger_without_guardian_sign(dsm, stranger): + assert dsm.isDepositsPaused() == False + + with reverts("ECDSA: invalid signature"): + dsm.pauseDeposits( + chain.height, + (0, 0), # skip signature + {"from": stranger}, + ) + + block_number=chain.height + non_guardian_private_key="0x" + "1" * 64 + sig = generate_pause_deposit_sig(dsm, block_number, non_guardian_private_key) + + with reverts(encode_error("InvalidSignature()")): + dsm.pauseDeposits(block_number, sig, {"from": stranger}) + diff --git a/utils/dsm.py b/utils/dsm.py index 044c0d032..9a01c848d 100644 --- a/utils/dsm.py +++ b/utils/dsm.py @@ -46,6 +46,21 @@ def sign(self, signer_private_key: str) -> Dict[str, Any]: signedMessage = Account.signHash(self.hash, signer_private_key) return to_eip2098(signedMessage) +class DSMPauseDepositsMessage(DSMMessage): + def __init__(self, block_number: int): + super().__init__() + self.block_number = block_number + + @property + def hash(self) -> str: + return Web3.solidity_keccak( + ["bytes32", "uint256"], + [ + self.message_prefix, + self.block_number + ] + ).hex() + class DSMUnvetMessage(DSMMessage): def __init__(self, block_number: int, block_hash: str, staking_module: int, nonce: int, From 840db3f18a44adee7fdcd495152520cbf9b0aa0d Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Fri, 18 Oct 2024 13:57:55 +0400 Subject: [PATCH 174/220] fix: description --- scripts/upgrade_sr_v2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index e6b239d32..70c0f6364 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -17,8 +17,8 @@ 15. Grant manage consensus role to Aragon Agent 16. Update Validator Exit Bus Oracle consensus version 17. Revoke manage consensus role from Aragon Agent -18. Remove old UpdateTargetValidatorLimits for SimpleDVT factory from EasyTrack -19. Add new UpdateTargetValidatorLimits for SimpleDVT factory to EasyTrack +18. Remove old UpdateTargetValidatorLimits factory for SimpleDVT from EasyTrack +19. Add new UpdateTargetValidatorLimits factory for SimpleDVT to EasyTrack Community Staking Module 20. Add Community Staking Module to Staking Router @@ -304,13 +304,13 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "18. Remove old UpdateTargetValidatorLimits for SimpleDVT factory from EasyTrack", + "18. Remove old UpdateTargetValidatorLimits factory for SimpleDVT from EasyTrack", remove_evmscript_factory( factory=OLD_TARGET_LIMIT_FACTORY, ), ), ( - "19. Add new UpdateTargetValidatorLimits for SimpleDVT factory to EasyTrack", + "19. Add new UpdateTargetValidatorLimits factory for SimpleDVT to EasyTrack", add_evmscript_factory( factory=EASYTRACK_SIMPLE_DVT_UPDATE_TARGET_VALIDATOR_LIMITS_FACTORY, permissions=( From 4169f38e4ec84cbc3c433822709314471c25dcae Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Fri, 18 Oct 2024 15:41:49 +0400 Subject: [PATCH 175/220] fix: remove silent false --- scripts/upgrade_sr_v2.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 70c0f6364..c059096a0 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -120,12 +120,12 @@ description = """ Release the Community Staking Module (CSM) for permissionless staking and upgrade the Staking Router to ensure compatibility with CSM and future modules, improving system efficiency. A detailed action plan can be found [on the research forum](https://research.lido.fi/t/staking-router-community-staking-module-upgrade-announcement/8612/6). -1. **Staking Router and related contracts upgrade** following the DAO-approved [LIP-25: Staking Router 2.0](https://snapshot.org/#/lido-snapshot.eth/proposal/0xffb4042d3bfceef33c66f78c092a76fa8e1db198559d93798cc9db3fb4d722e7) and [LIP-23: Negative rebase sanity check with a pluggable second opinion](https://snapshot.org/#/lido-snapshot.eth/proposal/0xa44f6a4dba07d7e24b0e4180025f7a9db6251046daa74d2a8fae84de0d9ce21e) designs. - -2. **Add Community Staking Module** to the Staking Router. CSM follows the [approved LIP-26 design and Mainnet Release Setup](https://snapshot.org/#/lido-snapshot.eth/proposal/0xd0d7bfd68f2241524dbb14ae6fe0e8414b9fe3e0dcfc50641a8d28f0067d6693). +1. **Staking Router and related contracts upgrade** following the DAO-approved [LIP-25: Staking Router 2.0](https://snapshot.org/#/lido-snapshot.eth/proposal/0xffb4042d3bfceef33c66f78c092a76fa8e1db198559d93798cc9db3fb4d722e7) and [LIP-23: Negative rebase sanity check with a pluggable second opinion](https://snapshot.org/#/lido-snapshot.eth/proposal/0xa44f6a4dba07d7e24b0e4180025f7a9db6251046daa74d2a8fae84de0d9ce21e) designs. -**Audits:** -[Staking Router 2.0 upgrade](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Staking%20Router%20v2%20Report%2010-24.pdf), [CSM](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Community%20Staking%20Module%20Report%2010-24.pdf) both with deployment verification by Ackee Blockchain; [Staking Router 2.0 & CSM](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20CSM%20Security%20Audit%20Report%2010-24.pdf), [Lido Oracle](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Oracle%20Security%20Audit%20Report%2010-24.pdf) (incl. CSM Oracle) by Mixbytes; +2. **Add Community Staking Module** to the Staking Router. CSM follows the [approved LIP-26 design and Mainnet Release Setup](https://snapshot.org/#/lido-snapshot.eth/proposal/0xd0d7bfd68f2241524dbb14ae6fe0e8414b9fe3e0dcfc50641a8d28f0067d6693). + +**Audits:** +[Staking Router 2.0 upgrade](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Staking%20Router%20v2%20Report%2010-24.pdf), [CSM](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Community%20Staking%20Module%20Report%2010-24.pdf) both with deployment verification by Ackee Blockchain; [Staking Router 2.0 & CSM](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20CSM%20Security%20Audit%20Report%2010-24.pdf), [Lido Oracle](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Oracle%20Security%20Audit%20Report%2010-24.pdf) (incl. CSM Oracle) by Mixbytes; The AccountingOracle (negative rebase parameters, pluggable second opinion) was part of Staking Router 2.0 upgrade audits and also audited separately: [Mixbytes report](https://github.com/lidofinance/audits/blob/main/Lido%20Sanity%20Checker%20Security%20Audit%20Report.pdf) and [ChainSecurity report](https://github.com/lidofinance/audits/blob/main/ChainSecurity%20Code%20Assessment%20of%20LIP-23%20Negative%20Rebase%20Checks%20Smart%20Contracts%2006-24.pdf). """ @@ -420,7 +420,7 @@ def main(): if get_is_live(): tx_params["priority_fee"] = get_priority_fee() - vote_id, _ = start_vote(tx_params=tx_params, silent=True) # disable temporary + vote_id, _ = start_vote(tx_params=tx_params, silent=False) vote_id >= 0 and print(f"Vote created: {vote_id}.") From 30e202653ee83f525e46fbad2cbb5c90f7710e54 Mon Sep 17 00:00:00 2001 From: zuzueeka Date: Fri, 18 Oct 2024 15:58:09 +0300 Subject: [PATCH 176/220] add new vote desc items --- scripts/upgrade_sr_v2.py | 72 ++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index c059096a0..f9f670000 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -1,31 +1,31 @@ """ Staking Router V2 -1. Update Locator implementation -2. Revoke pause role from old Deposit Security Module -3. Revoke resume role from old Deposit Security Module -4. Grant unvetting role to new Deposit Security Module -5. Update Staking Router implementation +1. Update Lido locator implementation to 0x3ABc4764f0237923d52056CFba7E9AEBf87113D3 +2. Revoke STAKING_MODULE_PAUSE_ROLE role on Staking Router from old Deposit Security Module +3. Revoke STAKING_MODULE_RESUME_ROLE role on Staking Router from old Deposit Security Module +4. Grant STAKING_MODULE_UNVETTING_ROLE role on Staking Router to new Deposit Security Module +5. Update Staking Router implementation to 0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA 6. Call finalize upgrade on Staking Router -7. Publish new Node Operators Registry implementation in Node Operators Registry app APM repo -8. Update Node Operators Registry implementation +7. Add new NodeOperatorsRegistry implementation to APM Node Operators Registry app repo +8. Update NodeOperatorsRegistry app. SetApp on Lido DAO (Kernel) 9. Finalize Node Operators Registry upgrade -10. Publish new SimpleDVT implementation in SimpleDVT app APM repo -11. Update SimpleDVT implementation +10. Add new SimpleDVT implementation to SimpleDVT app Repo +11. Update SimpleDVT app. SetApp on Lido DAO (Kernel) 12. Finalize SimpleDVT upgrade -13. Update Accounting Oracle implementation -14. Finalize Accounting Oracle upgrade and update consensus version -15. Grant manage consensus role to Aragon Agent -16. Update Validator Exit Bus Oracle consensus version -17. Revoke manage consensus role from Aragon Agent +13. Update Accounting Oracle implementation to 0x0e65898527E77210fB0133D00dd4C0E86Dc29bC7 +14. Finalize Accounting Oracle upgrade and set consensus version to 2 +15. Grant MANAGE_CONSENSUS_VERSION_ROLE role on Validator Exit Bus Oracle to Aragon Agent +16. Update Validator Exit Bus Oracle consensus version to 2 +17. Revoke MANAGE_CONSENSUS_VERSION_ROLE role on Validator Exit Bus Oracle from Aragon Agent 18. Remove old UpdateTargetValidatorLimits factory for SimpleDVT from EasyTrack 19. Add new UpdateTargetValidatorLimits factory for SimpleDVT to EasyTrack Community Staking Module -20. Add Community Staking Module to Staking Router -21. Grant request burn role to CSAccounting -22. Grant resume role to Aragon Agent +20. Add Community Staking Module 0xdA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F to Staking Router +21. Grant REQUEST_BURN_SHARES_ROLE role on Burner to CSAccounting +22. Grant RESUME_ROLE role on CSM to Aragon Agent 23. Resume Community Staking Module -24. Revoke resume role from Aragon Agent +24. Revoke RESUME_ROLE role on CSM from Aragon Agent 25. Update initial epoch on CSHashConsensus 26. Add CSMSettleElStealingPenalty factory to EasyTrack """ @@ -196,11 +196,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # SR 2 # ( - "1. Update Locator implementation", + "1. Update Lido locator implementation to 0x3ABc4764f0237923d52056CFba7E9AEBf87113D3", agent_forward([encode_locator_proxy_update(LIDO_LOCATOR_IMPL)]), ), ( - "2. Revoke pause role from old Deposit Security Module", + "2. Revoke STAKING_MODULE_PAUSE_ROLE role on Staking Router from old Deposit Security Module", agent_forward( [ encode_oz_revoke_role( @@ -212,7 +212,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "3. Revoke resume role from old Deposit Security Module", + "3. Revoke STAKING_MODULE_RESUME_ROLE role on Staking Router from old Deposit Security Module", agent_forward( [ encode_oz_revoke_role( @@ -224,7 +224,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "4. Grant unvetting role to new Deposit Security Module", + "4. Grant STAKING_MODULE_UNVETTING_ROLE role on Staking Router to new Deposit Security Module", agent_forward( [ encode_oz_grant_role( @@ -236,7 +236,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "5. Update Staking Router implementation", + "5. Update Staking Router implementation to 0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA", agent_forward([encode_staking_router_proxy_update(STAKING_ROUTER_IMPL)]), ), ( @@ -244,11 +244,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T encode_staking_router_finalize(), ), ( - "7. Publish new Node Operators Registry implementation in Node Operators Registry app APM repo", + "7. Add new NodeOperatorsRegistry implementation to APM Node Operators Registry app repo", add_implementation_to_nor_app_repo(NOR_VERSION_REPO, NODE_OPERATORS_REGISTRY_IMPL, nor_uri), ), ( - "8. Update Node Operators Registry implementation", + "8. Update NodeOperatorsRegistry app. SetApp on Lido DAO (Kernel)", update_app_implementation(NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), ), ( @@ -256,11 +256,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T encode_nor_finalize(), ), ( - "10. Publish new SimpleDVT implementation in SimpleDVT app APM repo", + "10. Add new SimpleDVT implementation to SimpleDVT app Repo", add_implementation_to_sdvt_app_repo(SDVT_VERSION_REPO, NODE_OPERATORS_REGISTRY_IMPL, simple_dvt_uri), ), ( - "11. Update SimpleDVT implementation", + "11. Update SimpleDVT app. SetApp on Lido DAO (Kernel)", update_app_implementation(SIMPLE_DVT_ARAGON_APP_ID, NODE_OPERATORS_REGISTRY_IMPL), ), ( @@ -268,15 +268,15 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T encode_sdvt_finalize(), ), ( - "13. Update Accounting Oracle implementation", + "13. Update Accounting Oracle implementation to 0x0e65898527E77210fB0133D00dd4C0E86Dc29bC7", agent_forward([encode_ao_proxy_update(ACCOUNTING_ORACLE_IMPL)]), ), ( - "14. Finalize Accounting Oracle upgrade and update consensus version", + "14. Finalize Accounting Oracle upgrade and set consensus version to 2", encode_ao_finalize(), ), ( - "15. Grant manage consensus role to Aragon Agent", + "15. Grant MANAGE_CONSENSUS_VERSION_ROLE role on Validator Exit Bus Oracle to Aragon Agent", agent_forward( [ encode_oz_grant_role( @@ -288,11 +288,11 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "16. Update Validator Exit Bus Oracle consensus version", + "16. Update Validator Exit Bus Oracle consensus version to 2", agent_forward([encode_set_consensus_version()]), ), ( - "17. Revoke manage consensus role from Aragon Agent", + "17. Revoke MANAGE_CONSENSUS_VERSION_ROLE role on Validator Exit Bus Oracle from Aragon Agent", agent_forward( [ encode_oz_revoke_role( @@ -323,7 +323,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T # # CSM ( - "20. Add Community Staking Module to Staking Router", + "20. Add Community Staking Module 0xdA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F to Staking Router", agent_forward( [ ( @@ -343,7 +343,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "21. Grant request burn role to CSAccounting", + "21. Grant REQUEST_BURN_SHARES_ROLE role on Burner to CSAccounting", agent_forward( [ encode_oz_grant_role( @@ -355,7 +355,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "22. Grant resume role to Aragon Agent", + "22. Grant RESUME_ROLE role on CSM to Aragon Agent", agent_forward( [ encode_oz_grant_role( @@ -371,7 +371,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T agent_forward([(contracts.csm.address, contracts.csm.resume.encode_input())]), ), ( - "24. Revoke resume role from Aragon Agent", + "24. Revoke RESUME_ROLE role on CSM from Aragon Agent", agent_forward( [ encode_oz_revoke_role( From 51e7c082e5f64fe1a49fd067765b8b3a0e8e6faf Mon Sep 17 00:00:00 2001 From: skhomuti Date: Fri, 18 Oct 2024 18:17:20 +0500 Subject: [PATCH 177/220] fill correct module with keys up to target share --- ...accounting_oracle_extra_data_full_items.py | 22 +------------------ .../test_staking_router_stake_distribution.py | 9 +++++--- utils/test/csm_helpers.py | 22 ++++++++++++++++++- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/tests/regression/test_accounting_oracle_extra_data_full_items.py b/tests/regression/test_accounting_oracle_extra_data_full_items.py index 61d151d64..4055f39d3 100644 --- a/tests/regression/test_accounting_oracle_extra_data_full_items.py +++ b/tests/regression/test_accounting_oracle_extra_data_full_items.py @@ -5,7 +5,7 @@ from brownie.network.account import Account from brownie.network.web3 import Web3 -from utils.test.csm_helpers import csm_add_node_operator, csm_upload_keys +from utils.test.csm_helpers import csm_add_node_operator, csm_upload_keys, fill_csm_operators_with_keys from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.helpers import shares_balance, almostEqWithDiff from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch @@ -320,26 +320,6 @@ def add_nor_operators_with_keys(nor, voting_eoa: Account, evm_script_executor_eo nor.setNodeOperatorStakingLimit(no_id, keys_per_operator, {"from": evm_script_executor_eoa}) -def fill_csm_operators_with_keys(target_operators_count, keys_count): - if not contracts.csm.publicRelease(): - contracts.csm.grantRole(contracts.csm.MODULE_MANAGER_ROLE(), contracts.agent, {"from": contracts.agent}) - contracts.csm.activatePublicRelease({"from": contracts.agent}) - - csm_node_operators_before = contracts.csm.getNodeOperatorsCount() - added_operators_count = 0 - for no_id in range(0, csm_node_operators_before): - depositable_keys = contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] - if depositable_keys < keys_count: - csm_upload_keys(contracts.csm, contracts.cs_accounting, no_id, keys_count - depositable_keys) - assert contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] == keys_count - while csm_node_operators_before + added_operators_count < target_operators_count: - node_operator = f"0xbb{str(added_operators_count).zfill(38)}" - csm_add_node_operator(contracts.csm, contracts.cs_accounting, node_operator, [], keys_count=keys_count) - added_operators_count += 1 - return csm_node_operators_before, added_operators_count - - - def fill_nor_with_old_and_new_operators( nor, voting_eoa, evm_script_executor_eoa, new_keys_per_operator, max_node_operators_per_item ) -> tuple[int, int]: diff --git a/tests/regression/test_staking_router_stake_distribution.py b/tests/regression/test_staking_router_stake_distribution.py index 53b7e0579..031405a80 100644 --- a/tests/regression/test_staking_router_stake_distribution.py +++ b/tests/regression/test_staking_router_stake_distribution.py @@ -1,7 +1,7 @@ from typing import Dict from utils.config import contracts -from utils.test.csm_helpers import csm_add_node_operator, get_ea_member +from utils.test.csm_helpers import csm_add_node_operator, get_ea_member, fill_csm_operators_with_keys from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.simple_dvt_helpers import fill_simple_dvt_ops_vetted_keys from utils.test.staking_router_helpers import StakingModuleStatus @@ -196,7 +196,7 @@ def test_target_share_distribution(stranger): assert module.allocated_keys < keys_to_allocate_double assert nor_m.allocated_keys <= keys_to_allocate_double - # aet the new target share value, which will be reached after 1s deposit of `keys_to_allocate`` batch + # set the new target share value, which will be reached after 1s deposit of `keys_to_allocate`` batch contracts.staking_router.updateStakingModule( module.id, expected_target_share_1, @@ -209,7 +209,10 @@ def test_target_share_distribution(stranger): ) # add enough depositable keys to the target module to overcome the target share # at least first 3 NOs, each with 1/3 of the `keys_to_allocate_double` available keys - fill_simple_dvt_ops_vetted_keys(stranger, 3, (module.deposited_keys + keys_to_allocate_double + 3) // 3) + if module.id == 2: + fill_simple_dvt_ops_vetted_keys(stranger, 3, (module.deposited_keys + keys_to_allocate_double + 3) // 3) + elif module.id == 3: + fill_csm_operators_with_keys(3, (module.deposited_keys + keys_to_allocate_double + 3) // 3) # update the modules info and recalc the allocation according to the module limits modules = get_modules_info(contracts.staking_router) diff --git a/utils/test/csm_helpers.py b/utils/test/csm_helpers.py index 0cbc86e6c..2897061ec 100644 --- a/utils/test/csm_helpers.py +++ b/utils/test/csm_helpers.py @@ -3,7 +3,7 @@ from utils.balance import set_balance_in_wei from utils.test.helpers import ETH from utils.test.keys_helpers import random_pubkeys_batch, random_signatures_batch - +from utils.config import contracts def get_ea_member(): """ @@ -157,3 +157,23 @@ def csm_upload_keys(csm, accounting, no_id, keys_count=5): {"from": manager_address, "value": accounting.getRequiredBondForNextKeys(no_id, keys_count)} ) + + +def fill_csm_operators_with_keys(target_operators_count, keys_count): + if not contracts.csm.publicRelease(): + contracts.csm.grantRole(contracts.csm.MODULE_MANAGER_ROLE(), contracts.agent, {"from": contracts.agent}) + contracts.csm.activatePublicRelease({"from": contracts.agent}) + + csm_node_operators_before = contracts.csm.getNodeOperatorsCount() + added_operators_count = 0 + for no_id in range(0, csm_node_operators_before): + depositable_keys = contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] + if depositable_keys < keys_count: + csm_upload_keys(contracts.csm, contracts.cs_accounting, no_id, keys_count - depositable_keys) + assert contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] == keys_count + while csm_node_operators_before + added_operators_count < target_operators_count: + node_operator = f"0xbb{str(added_operators_count).zfill(38)}" + csm_add_node_operator(contracts.csm, contracts.cs_accounting, node_operator, [], keys_count=keys_count) + added_operators_count += 1 + return csm_node_operators_before, added_operators_count + From da64cdde6ac64044284a3b339b22c899743a5942 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Fri, 18 Oct 2024 19:05:27 +0500 Subject: [PATCH 178/220] fix: topup 10 ether to execute votes by default --- tests/acceptance/conftest.py | 2 +- tests/conftest.py | 4 ++-- tests/regression/conftest.py | 2 +- tests/regression/test_pause_resume.py | 2 +- tests/snapshot/test_dsm.py | 2 +- tests/snapshot/test_first_slots.py | 2 +- tests/snapshot/test_legacy_oracle_snapshot.py | 2 +- tests/snapshot/test_lido_snapshot.py | 2 +- tests/snapshot/test_node_operators_registry.py | 2 +- tests/snapshot/test_plain_submit.py | 2 +- tests/snapshot/test_voting.py | 2 +- utils/import_current_votes.py | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/acceptance/conftest.py b/tests/acceptance/conftest.py index b51f84217..cfef7edea 100644 --- a/tests/acceptance/conftest.py +++ b/tests/acceptance/conftest.py @@ -15,7 +15,7 @@ @pytest.fixture(scope="module", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) def autoexecute_vote(helpers, vote_ids_from_env, accounts, stranger, module_isolation): if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) if os.getenv(ENV_FILL_SIMPLE_DVT): diff --git a/tests/conftest.py b/tests/conftest.py index 63fb41350..ad0c2857f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -104,12 +104,12 @@ def assert_event_not_emitted(evt_name, tx): raise AssertionError(f"Event {evt_name} was fired") @staticmethod - def execute_vote(accounts, vote_id, dao_voting, topup="1 ether", skip_time=MAINNET_VOTE_DURATION): + def execute_vote(accounts, vote_id, dao_voting, topup="10 ether", skip_time=MAINNET_VOTE_DURATION): (tx,) = Helpers.execute_votes(accounts, [vote_id], dao_voting, topup, skip_time) return tx @staticmethod - def execute_votes(accounts, vote_ids, dao_voting, topup="0.1 ether", skip_time=MAINNET_VOTE_DURATION): + def execute_votes(accounts, vote_ids, dao_voting, topup="10 ether", skip_time=MAINNET_VOTE_DURATION): OBJECTION_PHASE_ID = 1 for vote_id in vote_ids: print(f"Vote #{vote_id}") diff --git a/tests/regression/conftest.py b/tests/regression/conftest.py index 73d98a769..e906707e7 100644 --- a/tests/regression/conftest.py +++ b/tests/regression/conftest.py @@ -16,7 +16,7 @@ @pytest.fixture(scope="module", autouse=is_there_any_vote_scripts() or is_there_any_upgrade_scripts()) def autoexecute_vote(request, helpers, vote_ids_from_env, accounts, stranger, module_isolation): if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) diff --git a/tests/regression/test_pause_resume.py b/tests/regression/test_pause_resume.py index 576b79b6a..2d7816888 100644 --- a/tests/regression/test_pause_resume.py +++ b/tests/regression/test_pause_resume.py @@ -26,7 +26,7 @@ def burner() -> Contract: @pytest.fixture(scope="function", autouse=is_there_any_vote_scripts()) def autoexecute_vote(helpers, vote_ids_from_env, accounts): if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) diff --git a/tests/snapshot/test_dsm.py b/tests/snapshot/test_dsm.py index d0e06d4cb..d5e236d96 100644 --- a/tests/snapshot/test_dsm.py +++ b/tests/snapshot/test_dsm.py @@ -208,7 +208,7 @@ def _actions_snaps(dsm): v1_frames = tuple(_actions_snaps(dsm)) if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) diff --git a/tests/snapshot/test_first_slots.py b/tests/snapshot/test_first_slots.py index 111350ca8..ae977adcc 100644 --- a/tests/snapshot/test_first_slots.py +++ b/tests/snapshot/test_first_slots.py @@ -154,7 +154,7 @@ def _actions_snaps(): v1_frames = tuple(_actions_snaps()) if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) diff --git a/tests/snapshot/test_legacy_oracle_snapshot.py b/tests/snapshot/test_legacy_oracle_snapshot.py index ea4426584..817df4991 100644 --- a/tests/snapshot/test_legacy_oracle_snapshot.py +++ b/tests/snapshot/test_legacy_oracle_snapshot.py @@ -156,7 +156,7 @@ def _actions_snaps(): before = tuple(_actions_snaps()) if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) diff --git a/tests/snapshot/test_lido_snapshot.py b/tests/snapshot/test_lido_snapshot.py index 548c445aa..b8afaaf7b 100644 --- a/tests/snapshot/test_lido_snapshot.py +++ b/tests/snapshot/test_lido_snapshot.py @@ -399,7 +399,7 @@ def _actions_snaps(): v1_frames = tuple(_actions_snaps()) if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) diff --git a/tests/snapshot/test_node_operators_registry.py b/tests/snapshot/test_node_operators_registry.py index fb34462d8..4902f0e85 100644 --- a/tests/snapshot/test_node_operators_registry.py +++ b/tests/snapshot/test_node_operators_registry.py @@ -136,7 +136,7 @@ def create_actions(dsm_eoa): with chain_snapshot(): if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) snapshot_after_update = run_scenario(actions=create_actions(new_deposit_security_module_eoa), snapshooter=make_snapshot) diff --git a/tests/snapshot/test_plain_submit.py b/tests/snapshot/test_plain_submit.py index 31dc689c3..74286fd18 100644 --- a/tests/snapshot/test_plain_submit.py +++ b/tests/snapshot/test_plain_submit.py @@ -81,7 +81,7 @@ def steps() -> Dict[str, Dict[str, any]]: before: Dict[str, Dict[str, any]] = steps() chain.revert() if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) after: Dict[str, Dict[str, any]] = steps() diff --git a/tests/snapshot/test_voting.py b/tests/snapshot/test_voting.py index 4e3084bee..ef73f06a0 100644 --- a/tests/snapshot/test_voting.py +++ b/tests/snapshot/test_voting.py @@ -99,7 +99,7 @@ def test_create_wait_enact(helpers, vote_time, call_target, vote_ids_from_env): chain.revert() if vote_ids_from_env: - helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting, topup="0.5 ether") + helpers.execute_votes(accounts, vote_ids_from_env, contracts.voting) else: start_and_execute_votes(contracts.voting, helpers) after: Dict[str, Dict[str, any]] = steps(contracts.voting, call_target, vote_time) diff --git a/utils/import_current_votes.py b/utils/import_current_votes.py index a7c7f89d2..73005f71d 100644 --- a/utils/import_current_votes.py +++ b/utils/import_current_votes.py @@ -66,7 +66,7 @@ def start_and_execute_votes(dao_voting, helpers) -> tuple[List[str], List[Transa accounts[0].transfer(LDO_HOLDER_ADDRESS_FOR_TESTS, "10 ether") vote_id, _ = start_vote({"from": LDO_HOLDER_ADDRESS_FOR_TESTS}, silent=True) - (tx,) = helpers.execute_votes(accounts, [vote_id], dao_voting, topup="1 ether") + (tx,) = helpers.execute_votes(accounts, [vote_id], dao_voting, topup="10 ether") vote_ids.append(vote_id) vote_transactions.append(tx) return vote_ids, vote_transactions From 790f3e6f833c3bea97a268ec5f4d874902aeb1f5 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sat, 19 Oct 2024 00:22:44 +0400 Subject: [PATCH 179/220] fix: add more voting tests --- tests/test_upgrade_sr_v2.py | 125 +++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 23 deletions(-) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index 36fc01311..39c5ed5c2 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -72,6 +72,9 @@ NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" +# Easytrack +EASYTRACK = "0xF0211b7660680B49De1A7E9f25C65660F0a13Fea" + # Accounting oracle AO_CONSENSUS_VERSION = 2 @@ -223,39 +226,74 @@ def test_vote( burner = get_burner() csm = get_csm() csm_hash_consensus = get_csm_hash_consensus() - + ao = get_ao() + simple_dvt = get_simple_dvt() staking_router = get_staking_router() - assert staking_router.getStakingModulesCount() == 2 + easy_track = get_easy_track() # Before voting tests - # locator + # 1) Locator + # Check implementation address before vote check_ossifiable_proxy_impl(locator_proxy, OLD_LOCATOR_IMPL_ADDRESS) # DSM + # 2)-3) Check old DSM has STAKING_MODULE_PAUSE_ROLE, STAKING_MODULE_RESUME_ROLE + # 4) Check new DSM doesn't have STAKING_MODULE_UNVETTING_ROLE check_dsm_roles_before_vote() # SR + # 5) Check implementation address before vote check_ossifiable_proxy_impl(sr_proxy, OLD_SR_IMPL_ADDRESS) + # 6) Check Curated, SDVT modules before vote + # id, name, stakingModuleAddress, stakingModuleFee, treasuryFee, targetShare - match corresponding values in CURATED_MODULE_BEFORE_VOTE, SDVT_MODULE_BEFORE_VOTE + # priorityExitShareThreshold, maxDepositsPerBlock, minDepositBlockDistance - no values in SR yet check_module_before_vote(CURATED_MODULE_BEFORE_VOTE) check_module_before_vote(SDVT_MODULE_BEFORE_VOTE) + # Version + assert staking_router.getContractVersion() == 1 # NOR + # 7)-9) nor_app_repo = interface.Repo(NODE_OPERATORS_REGISTRY_REPO) - nor_old_app = nor_app_repo.getLatest() + # Check implementation address before vote assert nor_proxy.implementation() == OLD_NOR_IMPL + nor_old_app = nor_app_repo.getLatest() + # Check APM Node Operators Registry app repo has OLD_NOR_IMPL before vote + # version set to 4, Content URI without changes assert_repo_before_vote(nor_old_app, 4, OLD_NOR_IMPL, NOR_URI) # SDVT + # 10)-12) sdvt_app_repo = interface.Repo(SIMPLE_DVT_REPO) - sdvt_old_app = sdvt_app_repo.getLatest() + # Check implementation address before vote assert sdvt_proxy.implementation() == OLD_SDVT_IMPL + sdvt_old_app = sdvt_app_repo.getLatest() + # Check SimpleDVT app Repo repo has OLD_SDVT_IMPL before vote + # version set to 1, Content URI without changes assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, SDVT_URI) # AO + # 13) Check implementation check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) - # no permission to manage consensus version on agent - check_manage_consensus_role() - - # VEBO consensus version + # 14) Check AO contract version + assert ao.getContractVersion() == 1 + assert ao.getConsensusVersion() == 1 + + # VEBO + # 15), 17) Aragon Agent does not have MANAGE_CONSENSUS_VERSION_ROLE role + check_vebo_doesnt_have_manage_consensus_role() + # 16) Check consensus version assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 + # 18)-19) simple dvt has old factory + evm_script_factories_before = easy_track.getEVMScriptFactories() + assert OLD_TARGET_LIMIT_FACTORY in evm_script_factories_before + assert NEW_TARGET_LIMIT_FACTORY not in evm_script_factories_before + # 20) Two modules in SR + assert staking_router.getStakingModulesCount() == 2 + # 21) CSAccounting doesnt have burn role assert not burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + # 22), 24) Aragon Agent doesnt have resume role assert not csm.hasRole(RESUME_ROLE, AGENT) + # 23) CSM is on pause assert csm.isPaused() + # 25) epoch is not set yet + # 26) no factory for csm yet + assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY not in evm_script_factories_before # START VOTE if len(vote_ids_from_env) > 0: @@ -270,32 +308,69 @@ def test_vote( print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") - assert staking_router.getStakingModulesCount() == 3 - - # locator + # 1) Locator + # Check implementation address after vote check_ossifiable_proxy_impl(locator_proxy, NEW_LIDO_LOCATOR_IMPL) - # DSM + # 2)-4) DSM + # Check old dsm doesnt have STAKING_MODULE_PAUSE_ROLE, STAKING_MODULE_RESUME_ROLE + # Check new dsm has STAKING_MODULE_UNVETTING_ROLE check_dsm_roles_after_vote() # SR + # 5) implementation update check_ossifiable_proxy_impl(sr_proxy, NEW_STAKING_ROUTER_IMPL) + # 6) + # finalizeUpgrade_v2 + # Store the maxDepositsPerBlock, minDepositBlockDistance, priorityExitShareThreshold for Curated, Simple DVT modules in the Staking Router's state check_module_after_vote(CURATED_MODULE_AFTER_VOTE) check_module_after_vote(SDVT_MODULE_AFTER_VOTE) + # This also updates the contract version to 2 assert staking_router.getContractVersion() == 2 + # NOR + # 7)-9) + # Check implementation address after vote + assert nor_proxy.implementation() == NEW_NODE_OPERATORS_REGISTRY_IMPL + # Check APM Node Operators Registry app repo has NEW_NOR_IMPL after vote + # version set to 5, Content URI without changes + nor_new_app = nor_app_repo.getLatest() + assert_repo_update(nor_new_app, nor_old_app, NEW_NODE_OPERATORS_REGISTRY_IMPL, NOR_URI) + # SDVT + # 10)-12) + # Check implementation address after vote + assert sdvt_proxy.implementation() == NEW_SIMPLE_DVT_IMPL + # Check SimpleDVT app Repo repo has NEW_SDVT_IMPL before vote + # version set to 2, Content URI without changes + sdvt_new_app = sdvt_app_repo.getLatest() + assert_repo_update(sdvt_new_app, sdvt_old_app, NEW_SIMPLE_DVT_IMPL, SDVT_URI) # AO + # 13) check_ossifiable_proxy_impl(ao_proxy, NEW_ACCOUNTING_ORACLE_IMPL) - + # 14) Check AO contract version + assert ao.getContractVersion() == 2 + assert ao.getConsensusVersion() == 2 + # 15), 17) # no permission to manage consensus version on agent - check_manage_consensus_role() + check_vebo_doesnt_have_manage_consensus_role() + # 16) # VEBO consensus version assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION + # 18)-19) simple dvt has old factory + evm_script_factories_after = easy_track.getEVMScriptFactories() + assert OLD_TARGET_LIMIT_FACTORY not in evm_script_factories_after + assert NEW_TARGET_LIMIT_FACTORY in evm_script_factories_after + # 20) Two modules in SR + assert staking_router.getStakingModulesCount() == 3 + check_csm() + # 21) CSAccounting has request burn role assert burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + # 22), 24) Aragon Agent doesn't have resume_role assert not csm.hasRole(RESUME_ROLE, AGENT) + # 23) CSM is not on pause assert not csm.isPaused() - + # 25) Check epoch assert csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH - - check_csm() + # 26) Factory check + assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY in evm_script_factories_after # Events check display_voting_events(vote_tx) @@ -335,14 +410,10 @@ def test_vote( ], ) - nor_new_app = nor_app_repo.getLatest() - assert_repo_update(nor_new_app, nor_old_app, NEW_NODE_OPERATORS_REGISTRY_IMPL, NOR_URI) validate_repo_upgrade_event(events[6], RepoUpgrade(6, nor_new_app[0])) validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NEW_NODE_OPERATORS_REGISTRY_IMPL) validate_nor_update(events[8], NOR_VERSION) - sdvt_new_app = sdvt_app_repo.getLatest() - assert_repo_update(sdvt_new_app, sdvt_old_app, NEW_SIMPLE_DVT_IMPL, SDVT_URI) validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, NEW_SIMPLE_DVT_IMPL) validate_nor_update(events[11], SDVT_VERSION) @@ -438,6 +509,14 @@ def get_csm_hash_consensus(): return interface.CSHashConsensus(CS_ORACLE_HASH_CONSENSUS_ADDRESS) +def get_ao(): + return interface.AccountingOracle(ACCOUNTING_ORACLE) + + +def get_easy_track(): + return interface.EasyTrack(EASYTRACK) + + def check_ossifiable_proxy_impl(proxy, expected_impl): current_impl_address = proxy.proxy__getImplementation() assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" @@ -473,7 +552,7 @@ def check_dsm_roles_after_vote(): assert not old_dsm_has_resume_role -def check_manage_consensus_role(): +def check_vebo_doesnt_have_manage_consensus_role(): vebo = get_vebo() agent_has_manage_consensus_role = vebo.hasRole(MANAGE_CONSENSUS_VERSION_ROLE, AGENT) assert not agent_has_manage_consensus_role From a0729cd4d3f60bad21b64024e2d097340011d3ee Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sat, 19 Oct 2024 19:17:52 +0400 Subject: [PATCH 180/220] fix: comments to tests, epoch before vote check --- tests/test_upgrade_sr_v2.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index 39c5ed5c2..3ab7cb0ec 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -291,7 +291,8 @@ def test_vote( assert not csm.hasRole(RESUME_ROLE, AGENT) # 23) CSM is on pause assert csm.isPaused() - # 25) epoch is not set yet + # 25) epoch is set to far future epoch + assert csm_hash_consensus.getFrameConfig()[0] == 48038396021100853 # 26) no factory for csm yet assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY not in evm_script_factories_before @@ -354,11 +355,11 @@ def test_vote( # VEBO consensus version assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION - # 18)-19) simple dvt has old factory + # 18)-19) simple dvt has new factory evm_script_factories_after = easy_track.getEVMScriptFactories() assert OLD_TARGET_LIMIT_FACTORY not in evm_script_factories_after assert NEW_TARGET_LIMIT_FACTORY in evm_script_factories_after - # 20) Two modules in SR + # 20) Three modules in SR assert staking_router.getStakingModulesCount() == 3 check_csm() # 21) CSAccounting has request burn role From 9f85455d6a1af1b3d664f54b48aac8416f76382a Mon Sep 17 00:00:00 2001 From: maksim Date: Sat, 19 Oct 2024 17:44:55 +0200 Subject: [PATCH 181/220] test: restore deleted test --- tests/regression/test_pause_resume.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/regression/test_pause_resume.py b/tests/regression/test_pause_resume.py index 2d7816888..465a991dc 100644 --- a/tests/regression/test_pause_resume.py +++ b/tests/regression/test_pause_resume.py @@ -135,6 +135,22 @@ def test_revert_second_stop_resume(self): with brownie.reverts("CONTRACT_IS_ACTIVE"): contracts.lido.resume({"from": contracts.voting}) + @pytest.mark.skip( + reason="Second call of pause/resume staking is not reverted right now." + "It maybe should be fixed in the future to be consistent, " + "there's not a real problem with it." + ) + def test_revert_second_pause_resume_staking(self): + contracts.lido.pauseStaking({"from": contracts.voting}) + + with brownie.reverts(""): + contracts.lido.pauseStaking({"from": contracts.voting}) + + contracts.lido.resumeStaking({"from": contracts.voting}) + + with brownie.reverts(""): + contracts.lido.resumeStaking({"from": contracts.voting}) + def test_revert_second_stop_staking_module(self, helpers, stranger): contracts.staking_router.grantRole( web3.keccak(text="STAKING_MODULE_MANAGE_ROLE"), From 192336857e5b364eeb38e11f9007e06c5244b6f2 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sat, 19 Oct 2024 22:17:56 +0400 Subject: [PATCH 182/220] feat: add oracle rotation --- scripts/upgrade_sr_v2.py | 143 ++++++++++++++++++++++++++++++++++++ tests/test_upgrade_sr_v2.py | 56 +++++++++++++- 2 files changed, 198 insertions(+), 1 deletion(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index e6b239d32..47f5e7f92 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -28,6 +28,17 @@ 24. Revoke resume role from Aragon Agent 25. Update initial epoch on CSHashConsensus 26. Add CSMSettleElStealingPenalty factory to EasyTrack + +Instadapp oracle rotation + +27) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for AccountingOracle +28) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle +29) Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent +30) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from CSHashConsensus for CSFeeOracle +31) Add oracle member with address X to CSHashConsensus for AccountingOracle +32) Add oracle member with address X to CSHashConsensus for ValidatorsExitBusOracle +33) Add oracle member with address X to HashConsensus for ValidatorsExitBusOracle +34) Revoke MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus from Aragon Agent """ import time @@ -110,12 +121,24 @@ SIMPLE_DVT_MODULE_MIN_DEPOSITS_BLOCK_DISTANCE, ] +# Oracle quorum + +HASH_CONSENSUS_FOR_ACCOUNTING_ORACLE_QUORUM = 5 +HASH_CONSENSUS_FOR_VALIDATORS_EXIT_BUS_ORACLE_QUORUM = 5 + # CSM ## Easy track EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" ## Parameters CS_ORACLE_INITIAL_EPOCH = 326715 +HASH_CONSENSUS_FOR_CS_FEE_ORACLE_QUORUM = 5 + +# Oracles members +old_oracle_member_to_remove = "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d" +# RANDOM GENERATED ADDRESS, replace with actual oracle address +new_oracle_member_to_add = "0x4015CC4020730515C78D12170A8e9697E009D5E7" + description = """ Release the Community Staking Module (CSM) for permissionless staking and upgrade the Staking Router to ensure compatibility with CSM and future modules, improving system efficiency. A detailed action plan can be found [on the research forum](https://research.lido.fi/t/staking-router-community-staking-module-upgrade-announcement/8612/6). @@ -183,6 +206,42 @@ def get_repo_version(repo_address: str) -> tuple[int, int, int]: return contract["semanticVersion"] +def encode_remove_accounting_oracle_member(member: str, quorum: int) -> Tuple[str, str]: + hash_consensus = contracts.hash_consensus_for_accounting_oracle + + return (hash_consensus.address, hash_consensus.removeMember.encode_input(member, quorum)) + + +def encode_remove_validators_exit_bus_oracle_member(member: str, quorum: int) -> Tuple[str, str]: + hash_consensus = contracts.hash_consensus_for_validators_exit_bus_oracle + + return (hash_consensus.address, hash_consensus.removeMember.encode_input(member, quorum)) + + +def encode_remove_validators_cs_fee_oracle_member(member: str, quorum: int) -> Tuple[str, str]: + hash_consensus = contracts.csm_hash_consensus + + return (hash_consensus.address, hash_consensus.removeMember.encode_input(member, quorum)) + + +def encode_add_accounting_oracle_member(member: str, quorum: int) -> Tuple[str, str]: + hash_consensus = contracts.hash_consensus_for_accounting_oracle + + return (hash_consensus.address, hash_consensus.addMember.encode_input(member, quorum)) + + +def encode_add_validators_exit_bus_oracle_member(member: str, quorum: int) -> Tuple[str, str]: + hash_consensus = contracts.hash_consensus_for_validators_exit_bus_oracle + + return (hash_consensus.address, hash_consensus.addMember.encode_input(member, quorum)) + + +def encode_add_cs_fee_oracle_member(member: str, quorum: int) -> Tuple[str, str]: + hash_consensus = contracts.csm_hash_consensus + + return (hash_consensus.address, hash_consensus.addMember.encode_input(member, quorum)) + + def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[TransactionReceipt]]: """Prepare and run voting.""" @@ -400,6 +459,90 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T permissions=(create_permissions(contracts.csm, "settleELRewardsStealingPenalty")), ), ), + # Instadapp oracle rotation + ( + "27) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for AccountingOracle", + agent_forward( + [ + encode_remove_accounting_oracle_member( + old_oracle_member_to_remove, HASH_CONSENSUS_FOR_ACCOUNTING_ORACLE_QUORUM + ) + ], + ), + ), + ( + "28) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle", + agent_forward( + [ + encode_remove_validators_exit_bus_oracle_member( + old_oracle_member_to_remove, HASH_CONSENSUS_FOR_ACCOUNTING_ORACLE_QUORUM + ) + ], + ), + ), + ( + "29. Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent", + agent_forward( + [ + encode_oz_grant_role( + contract=contracts.csm_hash_consensus, + role_name="MANAGE_MEMBERS_AND_QUORUM_ROLE", + grant_to=contracts.agent, + ) + ] + ), + ), + ( + "30) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from CSHashConsensus for CSFeeOracle", + agent_forward( + [ + encode_remove_validators_cs_fee_oracle_member( + old_oracle_member_to_remove, + HASH_CONSENSUS_FOR_CS_FEE_ORACLE_QUORUM, + ) + ], + ), + ), + ( + "31) Add oracle member with address X to CSHashConsensus for AccountingOracle", + agent_forward( + [ + encode_add_accounting_oracle_member( + new_oracle_member_to_add, HASH_CONSENSUS_FOR_ACCOUNTING_ORACLE_QUORUM + ), + ] + ), + ), + ( + "32) Add oracle member with address X to CSHashConsensus for ValidatorsExitBusOracle", + agent_forward( + [ + encode_add_validators_exit_bus_oracle_member( + new_oracle_member_to_add, HASH_CONSENSUS_FOR_VALIDATORS_EXIT_BUS_ORACLE_QUORUM + ), + ] + ), + ), + ( + "33) Add oracle member with address X to HashConsensus for ValidatorsExitBusOracle", + agent_forward( + [ + encode_add_cs_fee_oracle_member(new_oracle_member_to_add, HASH_CONSENSUS_FOR_CS_FEE_ORACLE_QUORUM), + ] + ), + ), + ( + "34. Revoke MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus from Aragon Agent", + agent_forward( + [ + encode_oz_revoke_role( + contract=contracts.csm_hash_consensus, + role_name="MANAGE_MEMBERS_AND_QUORUM_ROLE", + revoke_from=contracts.agent, + ) + ] + ), + ), ) vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index 3ab7cb0ec..f42ba45db 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -28,6 +28,9 @@ BURNER = "0xD15a672319Cf0352560eE76d9e89eAB0889046D3" VOTING = "0x2e59A20f205bB85a89C53f1936454680651E618e" +HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" +HASH_CONSENSUS_FOR_VEBO = "0x7FaDB6358950c5fAA66Cb5EB8eE5147De3df355a" + # aragon repo NODE_OPERATORS_REGISTRY_REPO = "0x0D97E876ad14DB2b183CFeEB8aa1A5C788eB1831" SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" @@ -115,6 +118,12 @@ ## CSM RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" +MANAGE_MEMBERS_AND_QUORUM_ROLE = "0x66a484cf1a3c6ef8dfd59d24824943d2853a29d96f34a01271efc55774452a51" + +# Oracles members +old_oracle_member_to_remove = "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d" +# RANDOM GENERATED ADDRESS, replace with actual oracle address +new_oracle_member_to_add = "0x4015CC4020730515C78D12170A8e9697E009D5E7" class StakingModuleItem(NamedTuple): @@ -296,6 +305,25 @@ def test_vote( # 26) no factory for csm yet assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY not in evm_script_factories_before + # 27), 31) before vote old member still in the quorum of ao hash consensus, new member is not in the quorum + ao_hash_consensus = get_ao_hash_consensus() + assert ao_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert not ao_hash_consensus.getIsMember(new_oracle_member_to_add) + assert ao_hash_consensus.getQuorum() == 5 + # 28), 32) before vote old member still in the quorum of vebo hash consensus, new member is not in the quorum + vebo_hash_consensus = get_vebo_hash_consensus() + assert vebo_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert not vebo_hash_consensus.getIsMember(new_oracle_member_to_add) + assert vebo_hash_consensus.getQuorum() == 5 + + # 29), 34) agent doesnt have role + assert not csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) + + # 30), 33) after vote old member is in the quorum of cs hash consensus, new member is not in the quorum + assert csm_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert not csm_hash_consensus.getIsMember(new_oracle_member_to_add) + assert csm_hash_consensus.getQuorum() == 5 + # START VOTE if len(vote_ids_from_env) > 0: (vote_id,) = vote_ids_from_env @@ -373,11 +401,29 @@ def test_vote( # 26) Factory check assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY in evm_script_factories_after + # 27), 31) after vote old member is not in the quorum of ao hash consensus, new member is in the quorum + assert not ao_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert ao_hash_consensus.getIsMember(new_oracle_member_to_add) + assert ao_hash_consensus.getQuorum() == 5 + # 28), 32) after vote old member is not in the quorum of vebo hash consensus, new member is in the quorum + vebo_hash_consensus = get_vebo_hash_consensus() + assert not vebo_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert vebo_hash_consensus.getIsMember(new_oracle_member_to_add) + assert vebo_hash_consensus.getQuorum() == 5 + + # 29), 34) agent doesnt have role + assert not csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) + + # 30), 33) after vote old member is not in the quorum of cs hash consensus, new member is in the quorum + assert not csm_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert csm_hash_consensus.getIsMember(new_oracle_member_to_add) + assert csm_hash_consensus.getQuorum() == 5 + # Events check display_voting_events(vote_tx) events = group_voting_events(vote_tx) - assert len(events) == 26 + assert len(events) == 34 validate_upgrade_events(events[0], NEW_LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) @@ -518,6 +564,14 @@ def get_easy_track(): return interface.EasyTrack(EASYTRACK) +def get_ao_hash_consensus(): + return interface.HashConsensus(HASH_CONSENSUS_FOR_AO) + + +def get_vebo_hash_consensus(): + return interface.HashConsensus(HASH_CONSENSUS_FOR_VEBO) + + def check_ossifiable_proxy_impl(proxy, expected_impl): current_impl_address = proxy.proxy__getImplementation() assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" From 85b8e2d6e1aef8088d188480f185e14bb68d2277 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sat, 19 Oct 2024 23:30:42 +0400 Subject: [PATCH 183/220] fix: add new oracle address, removed MANAGE_MEMBERS_AND_QUORUM_ROLE role on cs hash consensus revoke from Agent --- scripts/upgrade_sr_v2.py | 40 ++++++++++++++++++------------------- tests/test_upgrade_sr_v2.py | 7 +++---- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 1ed4e3022..5b6cda7ea 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -35,10 +35,9 @@ 28) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle 29) Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent 30) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from CSHashConsensus for CSFeeOracle -31) Add oracle member with address X to CSHashConsensus for AccountingOracle -32) Add oracle member with address X to CSHashConsensus for ValidatorsExitBusOracle -33) Add oracle member with address X to HashConsensus for ValidatorsExitBusOracle -34) Revoke MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus from Aragon Agent +31) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for AccountingOracle +32) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for ValidatorsExitBusOracle +33) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle """ import time @@ -136,8 +135,7 @@ # Oracles members old_oracle_member_to_remove = "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d" -# RANDOM GENERATED ADDRESS, replace with actual oracle address -new_oracle_member_to_add = "0x4015CC4020730515C78D12170A8e9697E009D5E7" +new_oracle_member_to_add = "0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12" description = """ @@ -504,7 +502,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "31) Add oracle member with address X to CSHashConsensus for AccountingOracle", + "31) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for AccountingOracle", agent_forward( [ encode_add_accounting_oracle_member( @@ -514,7 +512,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "32) Add oracle member with address X to CSHashConsensus for ValidatorsExitBusOracle", + "32) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for ValidatorsExitBusOracle", agent_forward( [ encode_add_validators_exit_bus_oracle_member( @@ -524,25 +522,25 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "33) Add oracle member with address X to HashConsensus for ValidatorsExitBusOracle", + "33) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle", agent_forward( [ encode_add_cs_fee_oracle_member(new_oracle_member_to_add, HASH_CONSENSUS_FOR_CS_FEE_ORACLE_QUORUM), ] ), ), - ( - "34. Revoke MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus from Aragon Agent", - agent_forward( - [ - encode_oz_revoke_role( - contract=contracts.csm_hash_consensus, - role_name="MANAGE_MEMBERS_AND_QUORUM_ROLE", - revoke_from=contracts.agent, - ) - ] - ), - ), + # ( + # "34. Revoke MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus from Aragon Agent", + # agent_forward( + # [ + # encode_oz_revoke_role( + # contract=contracts.csm_hash_consensus, + # role_name="MANAGE_MEMBERS_AND_QUORUM_ROLE", + # revoke_from=contracts.agent, + # ) + # ] + # ), + # ), ) vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index 99ce04ac1..e536322c0 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -122,8 +122,7 @@ # Oracles members old_oracle_member_to_remove = "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d" -# RANDOM GENERATED ADDRESS, replace with actual oracle address -new_oracle_member_to_add = "0x4015CC4020730515C78D12170A8e9697E009D5E7" +new_oracle_member_to_add = "0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12" class StakingModuleItem(NamedTuple): @@ -412,7 +411,7 @@ def test_vote( assert vebo_hash_consensus.getQuorum() == 5 # 29), 34) agent doesnt have role - assert not csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) + assert csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) # 30), 33) after vote old member is not in the quorum of cs hash consensus, new member is in the quorum assert not csm_hash_consensus.getIsMember(old_oracle_member_to_remove) @@ -423,7 +422,7 @@ def test_vote( display_voting_events(vote_tx) events = group_voting_events(vote_tx) - assert len(events) == 34 + assert len(events) == 33 validate_upgrade_events(events[0], NEW_LIDO_LOCATOR_IMPL) validate_dsm_roles_events(events) From 6f624f999afd0f50be40d7f92e078a8c59ae9580 Mon Sep 17 00:00:00 2001 From: maksim Date: Sat, 19 Oct 2024 21:57:37 +0200 Subject: [PATCH 184/220] test: rotate oracle member Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for all oracles Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for all oracles Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent --- configs/config_mainnet.py | 3 ++- tests/regression/test_permissions.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 2469c4db5..1c784fe60 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -246,8 +246,9 @@ "0xc79F702202E3A6B0B6310B537E786B9ACAA19BAf", # Added into members in vote 2024/01/16 # "0xEC4BfbAF681eb505B94E4a7849877DC6c600Ca3A", Excluded from members in vote 2024/08/06 "0x61c91ECd902EB56e314bB2D5c5C07785444Ea1c8", - "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d", + # "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d", Excluded from members in vote 2024/10/22 "0xe57B3792aDCc5da47EF4fF588883F0ee0c9835C9", # Added into members in vote 2024/08/06 + "0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12" # Added into members in vote 2024/10/22 ) # WithdrawalQueueERC721 diff --git a/tests/regression/test_permissions.py b/tests/regression/test_permissions.py index 3a8d8a47a..519f85956 100644 --- a/tests/regression/test_permissions.py +++ b/tests/regression/test_permissions.py @@ -368,7 +368,7 @@ def protocol_permissions(): "type": "CustomApp", "roles": { "DEFAULT_ADMIN_ROLE": [contracts.agent], - "MANAGE_MEMBERS_AND_QUORUM_ROLE": [], + "MANAGE_MEMBERS_AND_QUORUM_ROLE": [contracts.agent], "DISABLE_CONSENSUS_ROLE": [], "MANAGE_FRAME_CONFIG_ROLE": [], "MANAGE_FAST_LANE_CONFIG_ROLE": [], From 9721c1d54d345be343f6fc2e63f08671df8cfcc1 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sun, 20 Oct 2024 10:59:25 +0400 Subject: [PATCH 185/220] Update scripts/upgrade_sr_v2.py Co-authored-by: avsetsin --- scripts/upgrade_sr_v2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 5b6cda7ea..5ad490cad 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -35,9 +35,9 @@ 28) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle 29) Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent 30) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from CSHashConsensus for CSFeeOracle -31) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for AccountingOracle -32) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for ValidatorsExitBusOracle -33) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle +31) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for AccountingOracle +32) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle +33) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for CSFeeOracle """ import time From 2d6dfbf2fcc8e1195f0f8e4c4670f9dd8181551b Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sun, 20 Oct 2024 10:59:38 +0400 Subject: [PATCH 186/220] Update scripts/upgrade_sr_v2.py Co-authored-by: avsetsin --- scripts/upgrade_sr_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 5ad490cad..4d08a8e3c 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -479,7 +479,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "29. Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent", + "29. Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent", agent_forward( [ encode_oz_grant_role( From 47c32b20110c4010b38c60529adb31fac46a4b2f Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sun, 20 Oct 2024 10:59:47 +0400 Subject: [PATCH 187/220] Update scripts/upgrade_sr_v2.py Co-authored-by: avsetsin --- scripts/upgrade_sr_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 4d08a8e3c..28c843666 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -502,7 +502,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "31) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for AccountingOracle", + "31) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for AccountingOracle", agent_forward( [ encode_add_accounting_oracle_member( From 5b79386bf0dafa87f2dc90f721ab23dea88373e9 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sun, 20 Oct 2024 10:59:56 +0400 Subject: [PATCH 188/220] Update scripts/upgrade_sr_v2.py Co-authored-by: avsetsin --- scripts/upgrade_sr_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 28c843666..4abab767f 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -512,7 +512,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "32) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for ValidatorsExitBusOracle", + "32) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle", agent_forward( [ encode_add_validators_exit_bus_oracle_member( From dcc802688122844031bd3bf84ff63883e158d116 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sun, 20 Oct 2024 11:00:04 +0400 Subject: [PATCH 189/220] Update scripts/upgrade_sr_v2.py Co-authored-by: avsetsin --- scripts/upgrade_sr_v2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 4abab767f..e25264ca4 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -522,7 +522,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "33) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle", + "33) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for CSFeeOracle", agent_forward( [ encode_add_cs_fee_oracle_member(new_oracle_member_to_add, HASH_CONSENSUS_FOR_CS_FEE_ORACLE_QUORUM), From 710be0d37ad8f816bce3964084d31cd23858fd9a Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sun, 20 Oct 2024 11:05:18 +0400 Subject: [PATCH 190/220] fix: small comment fixes --- scripts/upgrade_sr_v2.py | 12 ------------ tests/test_upgrade_sr_v2.py | 10 +++++----- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index e25264ca4..abc081036 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -529,18 +529,6 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ] ), ), - # ( - # "34. Revoke MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus from Aragon Agent", - # agent_forward( - # [ - # encode_oz_revoke_role( - # contract=contracts.csm_hash_consensus, - # role_name="MANAGE_MEMBERS_AND_QUORUM_ROLE", - # revoke_from=contracts.agent, - # ) - # ] - # ), - # ), ) vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index e536322c0..1aa8e33a1 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -304,21 +304,21 @@ def test_vote( # 26) no factory for csm yet assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY not in evm_script_factories_before - # 27), 31) before vote old member still in the quorum of ao hash consensus, new member is not in the quorum + # 27), 31) before vote old member is still in the quorum of ao hash consensus, new member is not in the quorum ao_hash_consensus = get_ao_hash_consensus() assert ao_hash_consensus.getIsMember(old_oracle_member_to_remove) assert not ao_hash_consensus.getIsMember(new_oracle_member_to_add) assert ao_hash_consensus.getQuorum() == 5 - # 28), 32) before vote old member still in the quorum of vebo hash consensus, new member is not in the quorum + # 28), 32) before vote old member is still in the quorum of vebo hash consensus, new member is not in the quorum vebo_hash_consensus = get_vebo_hash_consensus() assert vebo_hash_consensus.getIsMember(old_oracle_member_to_remove) assert not vebo_hash_consensus.getIsMember(new_oracle_member_to_add) assert vebo_hash_consensus.getQuorum() == 5 - # 29), 34) agent doesnt have role + # 29) agent doesnt have role assert not csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) - # 30), 33) after vote old member is in the quorum of cs hash consensus, new member is not in the quorum + # 30), 33) before vote old member is still in the quorum of cs hash consensus, new member is not in the quorum assert csm_hash_consensus.getIsMember(old_oracle_member_to_remove) assert not csm_hash_consensus.getIsMember(new_oracle_member_to_add) assert csm_hash_consensus.getQuorum() == 5 @@ -410,7 +410,7 @@ def test_vote( assert vebo_hash_consensus.getIsMember(new_oracle_member_to_add) assert vebo_hash_consensus.getQuorum() == 5 - # 29), 34) agent doesnt have role + # 29) agent doesnt have role assert csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) # 30), 33) after vote old member is not in the quorum of cs hash consensus, new member is in the quorum From 38509b97f79bc907f4e4d4617899f3ac81228ac0 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Sun, 20 Oct 2024 12:16:31 +0400 Subject: [PATCH 191/220] fix: add events tests for oracle rotation --- tests/test_upgrade_sr_v2.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index 1aa8e33a1..fffcdbfca 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -15,6 +15,10 @@ EVMScriptFactoryAdded, ) from utils.easy_track import create_permissions, create_permissions_overloaded +from utils.test.event_validators.hash_consensus import ( + validate_hash_consensus_member_removed, + validate_hash_consensus_member_added, +) # Addresses that will not be changed @@ -518,6 +522,29 @@ def test_vote( ["LogScriptCall", "EVMScriptFactoryAdded", "ScriptResult", "ExecuteVote"], ) + validate_hash_consensus_member_removed(events[26], old_oracle_member_to_remove, 5, new_total_members=8) + validate_hash_consensus_member_removed(events[27], old_oracle_member_to_remove, 5, new_total_members=8) + validate_grant_role_event(events[28], MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT, AGENT) + validate_hash_consensus_member_removed( + events[29], + old_oracle_member_to_remove, + 5, + new_total_members=8, + ) + validate_hash_consensus_member_added(events[30], new_oracle_member_to_add, 5, new_total_members=9) + validate_hash_consensus_member_added( + events[31], + new_oracle_member_to_add, + 5, + new_total_members=9, + ) + validate_hash_consensus_member_added( + events[32], + new_oracle_member_to_add, + 5, + new_total_members=9, + ) + def get_staking_router(): return interface.StakingRouter(STAKING_ROUTER) From 732d6695c1f5ae0e34ae82549af97edd489c67dd Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 21 Oct 2024 09:22:52 +0400 Subject: [PATCH 192/220] fix: minor fix of item desc --- scripts/upgrade_sr_v2.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index abc081036..100c0fe9f 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -31,13 +31,13 @@ Instadapp oracle rotation -27) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for AccountingOracle -28) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle -29) Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent -30) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from CSHashConsensus for CSFeeOracle -31) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for AccountingOracle -32) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle -33) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for CSFeeOracle +27. Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for AccountingOracle +28. Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle +29. Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent +30. Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from CSHashConsensus for CSFeeOracle +31. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for AccountingOracle +32. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle +33. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for CSFeeOracle """ import time @@ -459,7 +459,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), # Instadapp oracle rotation ( - "27) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for AccountingOracle", + "27. Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for AccountingOracle", agent_forward( [ encode_remove_accounting_oracle_member( @@ -469,7 +469,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "28) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle", + "28. Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle", agent_forward( [ encode_remove_validators_exit_bus_oracle_member( @@ -491,7 +491,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "30) Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from CSHashConsensus for CSFeeOracle", + "30. Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from CSHashConsensus for CSFeeOracle", agent_forward( [ encode_remove_validators_cs_fee_oracle_member( @@ -502,7 +502,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "31) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for AccountingOracle", + "31. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for AccountingOracle", agent_forward( [ encode_add_accounting_oracle_member( @@ -512,7 +512,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "32) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle", + "32. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle", agent_forward( [ encode_add_validators_exit_bus_oracle_member( @@ -522,7 +522,7 @@ def start_vote(tx_params: Dict[str, str], silent: bool) -> Tuple[int, Optional[T ), ), ( - "33) Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for CSFeeOracle", + "33. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for CSFeeOracle", agent_forward( [ encode_add_cs_fee_oracle_member(new_oracle_member_to_add, HASH_CONSENSUS_FOR_CS_FEE_ORACLE_QUORUM), From aaa09ec090274bfcfe102fa7803f32ca9d0cfa99 Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 21 Oct 2024 09:31:55 +0400 Subject: [PATCH 193/220] fix: removed space --- scripts/upgrade_sr_v2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index 100c0fe9f..b9b72fcf4 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -30,7 +30,6 @@ 26. Add CSMSettleElStealingPenalty factory to EasyTrack Instadapp oracle rotation - 27. Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for AccountingOracle 28. Remove the oracle member with address 0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d from HashConsensus for ValidatorsExitBusOracle 29. Grant MANAGE_MEMBERS_AND_QUORUM_ROLE role on CSHashConsensus to Aragon Agent From 4fbd777ad94385edf05316cb7750130175dce04f Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 21 Oct 2024 09:39:51 +0400 Subject: [PATCH 194/220] fix: remove file added by mistake --- scripts/rules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 scripts/rules diff --git a/scripts/rules b/scripts/rules deleted file mode 100644 index 3720fb056..000000000 --- a/scripts/rules +++ /dev/null @@ -1,3 +0,0 @@ -1. в тестах воутинга указать адреса явно и параметры -2. в воутинг скрипте импортируем из конфига -3. импортируем в скрипте адреса \ No newline at end of file From c3d0a71f396dcf3c3803dddc289050b22ce955fd Mon Sep 17 00:00:00 2001 From: skhomuti Date: Mon, 21 Oct 2024 12:21:53 +0500 Subject: [PATCH 195/220] fix: review changes in csm tests --- tests/regression/test_csm.py | 34 +++++++++++-------- .../test_staking_module_happy_path.py | 7 +--- utils/staking_module.py | 7 ++++ 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py index 897c9cd36..dd6fa7d11 100644 --- a/tests/regression/test_csm.py +++ b/tests/regression/test_csm.py @@ -9,6 +9,7 @@ ) from utils.dsm import UnvetArgs, to_bytes, set_single_guardian from utils.evm_script import encode_error +from utils.staking_module import calc_module_reward_shares from utils.test.csm_helpers import csm_add_node_operator, get_ea_member, csm_upload_keys, get_ea_members from utils.test.deposits_helpers import fill_deposit_buffer from utils.test.helpers import ETH @@ -117,11 +118,12 @@ def test_deposit(node_operator, csm): def test_mint_rewards_happy_path(csm, fee_distributor): csm_shares_before = contracts.lido.sharesOf(csm) fee_distributor_shares_before = contracts.lido.sharesOf(fee_distributor) - - oracle_report(cl_diff=ETH(1)) + (report_tx, _) = oracle_report() + minted_shares = report_tx.events["TokenRebased"]["sharesMintedAsFees"] + csm_distributed_rewards = calc_module_reward_shares(CSM_MODULE_ID, minted_shares) assert csm_shares_before == contracts.lido.sharesOf(csm) - assert contracts.lido.sharesOf(fee_distributor) > fee_distributor_shares_before + assert contracts.lido.sharesOf(fee_distributor) == fee_distributor_shares_before + csm_distributed_rewards def test_csm_target_limits(csm, node_operator): @@ -266,37 +268,40 @@ def test_csm_decrease_vetted_keys(csm, node_operator, stranger): @pytest.mark.usefixtures("deposits_to_csm") def test_csm_penalize_node_operator(csm, accounting, node_operator, helpers): - bond_before = accounting.getBond(node_operator) + bond_shares_before = accounting.getBondShares(node_operator) tx = csm.submitInitialSlashing(node_operator, 0, {"from": contracts.cs_verifier}) assert "StETHBurnRequested" in tx.events - assert accounting.getBond(node_operator) < bond_before + burnt_shares = tx.events["StETHBurnRequested"]["amountOfShares"] + assert accounting.getBondShares(node_operator) == bond_shares_before - burnt_shares @pytest.mark.usefixtures("deposits_to_csm") -def test_csm_deposit_eth(csm, accounting, node_operator): +def test_csm_eth_bond(csm, accounting, node_operator): manager_address = csm.getNodeOperator(node_operator)["managerAddress"] set_balance_in_wei(manager_address, ETH(2)) - bond_before = accounting.getBond(node_operator) + bond_shares_before = accounting.getBondShares(node_operator) + shares = contracts.lido.getSharesByPooledEth(ETH(1)) csm.depositETH(node_operator, {"from": manager_address, "value": ETH(1)}) - assert accounting.getBond(node_operator) > bond_before + assert accounting.getBondShares(node_operator) == bond_shares_before + shares @pytest.mark.usefixtures("deposits_to_csm") -def test_csm_deposit_steth(csm, accounting, node_operator): +def test_csm_steth_bond(csm, accounting, node_operator): manager_address = csm.getNodeOperator(node_operator)["managerAddress"] set_balance_in_wei(manager_address, ETH(2)) - bond_before = accounting.getBond(node_operator) + bond_shares_before = accounting.getBondShares(node_operator) contracts.lido.submit(ZERO_ADDRESS, {"from": manager_address, "value": ETH(1.5)}) contracts.lido.approve(accounting, ETH(2), {"from": manager_address}) + shares = contracts.lido.getSharesByPooledEth(ETH(1)) csm.depositStETH(node_operator, ETH(1), (0, 0, 0, 0, 0), {"from": manager_address}) - assert accounting.getBond(node_operator) > bond_before + assert accounting.getBondShares(node_operator) == bond_shares_before + shares @pytest.mark.usefixtures("deposits_to_csm") -def test_csm_deposit_wsteth(csm, accounting, node_operator): +def test_csm_wsteth_bond(csm, accounting, node_operator): manager_address = csm.getNodeOperator(node_operator)["managerAddress"] set_balance_in_wei(manager_address, ETH(2)) contracts.lido.submit(ZERO_ADDRESS, {"from": manager_address, "value": ETH(1.5)}) @@ -304,9 +309,10 @@ def test_csm_deposit_wsteth(csm, accounting, node_operator): contracts.wsteth.wrap(ETH(1.5), {"from": manager_address}) contracts.wsteth.approve(accounting, contracts.wsteth.balanceOf(manager_address), {"from": manager_address}) - bond_before = accounting.getBond(node_operator) + shares = contracts.lido.getSharesByPooledEth(contracts.wsteth.getStETHByWstETH(contracts.wsteth.balanceOf(manager_address))) + bond_shares_before = accounting.getBondShares(node_operator) csm.depositWstETH(node_operator, contracts.wsteth.balanceOf(manager_address), (0, 0, 0, 0, 0), {"from": manager_address}) - assert accounting.getBond(node_operator) > bond_before + assert accounting.getBondShares(node_operator) == bond_shares_before + shares @pytest.mark.usefixtures("deposits_to_csm") diff --git a/tests/regression/test_staking_module_happy_path.py b/tests/regression/test_staking_module_happy_path.py index 718e2a3e3..7c1672486 100644 --- a/tests/regression/test_staking_module_happy_path.py +++ b/tests/regression/test_staking_module_happy_path.py @@ -3,6 +3,7 @@ import eth_abi from brownie import chain, ZERO_ADDRESS, web3 +from utils.staking_module import calc_module_reward_shares from utils.test.extra_data import ( ExtraDataService, ) @@ -24,12 +25,6 @@ def impersonated_voting(accounts): return accounts.at(contracts.voting.address, force=True) -def calc_module_reward_shares(module_id, shares_minted_as_fees): - distribution = contracts.staking_router.getStakingRewardsDistribution() - module_idx = distribution[1].index(module_id) - return distribution[2][module_idx] * shares_minted_as_fees // distribution[3] - - def calc_no_rewards(nor, no_id, minted_shares): operator_summary = nor.getNodeOperatorSummary(no_id) module_summary = nor.getStakingModuleSummary() diff --git a/utils/staking_module.py b/utils/staking_module.py index 7b639b44b..daaf58133 100644 --- a/utils/staking_module.py +++ b/utils/staking_module.py @@ -22,3 +22,10 @@ def add_node_operator(staking_module, voting, stranger): staking_module.addNodeOperator("test", f"0xbb{str(1).zfill(38)}", {"from": stranger} ) return operator_id + + +def calc_module_reward_shares(module_id, shares_minted_as_fees): + distribution = contracts.staking_router.getStakingRewardsDistribution() + module_idx = distribution[1].index(module_id) + return distribution[2][module_idx] * shares_minted_as_fees // distribution[3] + From b3e724bec58ffdb7064daae5f0f93b8e2633ba3d Mon Sep 17 00:00:00 2001 From: Ivan Feofanov Date: Mon, 21 Oct 2024 09:32:38 +0200 Subject: [PATCH 196/220] fix: return EasyTrack check --- .github/workflows/large_vote_ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/large_vote_ci.yml b/.github/workflows/large_vote_ci.yml index f1c3e1ffe..7d5513c9f 100644 --- a/.github/workflows/large_vote_ci.yml +++ b/.github/workflows/large_vote_ci.yml @@ -17,6 +17,18 @@ jobs: runs-on: [protocol-heavy-runners] timeout-minutes: 150 steps: + - name: Enabling swap + run: | + sudo df -h + sudo swapon --show + sudo swapoff -a + sudo rm /swapfile + sudo touch /swapfile + sudo fallocate -l 32G /swapfile + sudo chmod 600 /swapfile + sudo mkswap /swapfile + sudo swapon /swapfile + sudo swapon --show - uses: actions/checkout@v3 - name: Main action uses: ./.github/actions/brownie_fork_tests From 74ee60b2c755796d5e8a86d2d1faf0037b0c4c61 Mon Sep 17 00:00:00 2001 From: Ivan Feofanov Date: Mon, 21 Oct 2024 09:36:50 +0200 Subject: [PATCH 197/220] fix: rm rm --- .github/workflows/large_vote_ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/large_vote_ci.yml b/.github/workflows/large_vote_ci.yml index 7d5513c9f..255d0300d 100644 --- a/.github/workflows/large_vote_ci.yml +++ b/.github/workflows/large_vote_ci.yml @@ -22,7 +22,6 @@ jobs: sudo df -h sudo swapon --show sudo swapoff -a - sudo rm /swapfile sudo touch /swapfile sudo fallocate -l 32G /swapfile sudo chmod 600 /swapfile From cb00e694af942cc3a500489e85d29be4f7301741 Mon Sep 17 00:00:00 2001 From: maksim Date: Mon, 21 Oct 2024 11:00:41 +0200 Subject: [PATCH 198/220] test: simplify staking router helper --- utils/test/staking_router_helpers.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/utils/test/staking_router_helpers.py b/utils/test/staking_router_helpers.py index a77342dac..1da92b662 100644 --- a/utils/test/staking_router_helpers.py +++ b/utils/test/staking_router_helpers.py @@ -7,15 +7,5 @@ class StakingModuleStatus(IntEnum): DepositsPaused = 1 Stopped = 2 -new_staking_module_manager_address = "0xB871BB28d7e6Be4A373ed7a2DD6733a7423dC089" -staking_router_manager_role = web3.keccak(text="STAKING_MODULE_MANAGE_ROLE") - def set_staking_module_status(module_id, staking_module_status: StakingModuleStatus): - if(not contracts.staking_router.hasRole(staking_router_manager_role, new_staking_module_manager_address)): - contracts.staking_router.grantRole( - staking_router_manager_role, - new_staking_module_manager_address, - {"from": contracts.agent}, - ) - - contracts.staking_router.setStakingModuleStatus(module_id, staking_module_status, {"from": new_staking_module_manager_address}) + contracts.staking_router.setStakingModuleStatus(module_id, staking_module_status, {"from": contracts.agent}) From 0a8a65068f2dc9a99a2e70d4be6433b67e0d5546 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Mon, 21 Oct 2024 14:22:09 +0500 Subject: [PATCH 199/220] update snapshot test after editing hash consensus members in the vote --- tests/snapshot/test_first_slots.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/snapshot/test_first_slots.py b/tests/snapshot/test_first_slots.py index ae977adcc..3b2c09c81 100644 --- a/tests/snapshot/test_first_slots.py +++ b/tests/snapshot/test_first_slots.py @@ -16,7 +16,7 @@ from .utils import get_slot SLOTS_COUNT_TO_CHECK = 16 -MAX_ARRAY_SIZE = 2**5 +MAX_ARRAY_SIZE = 2 ** 5 class Frame(TypedDict): @@ -63,7 +63,10 @@ def skip_slots() -> Sequence[tuple[str, int]]: # evmScriptFactories array (contracts.easy_track.address, 5), # Set initial epoch for CSM hash consensus - (contracts.csm_hash_consensus.address, 0) + (contracts.csm_hash_consensus.address, 0), + # change hash consensus members + (contracts.csm_hash_consensus.address, 2) + ] From f55db6a8d608b211a35893f66b355695c36688ee Mon Sep 17 00:00:00 2001 From: Anna Mukharram Date: Mon, 21 Oct 2024 13:22:21 +0400 Subject: [PATCH 200/220] fix: added nor/sdvt version tests --- tests/test_upgrade_sr_v2.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py index fffcdbfca..eeb6f99e9 100644 --- a/tests/test_upgrade_sr_v2.py +++ b/tests/test_upgrade_sr_v2.py @@ -98,6 +98,9 @@ SDVT_VERSION = 3 AO_VERSION = 2 +OLD_NOR_VERSION = 2 +OLD_SDVT_VERSION = 2 + # CSM parameters CS_MODULE_NAME = "Community Staking" @@ -242,6 +245,7 @@ def test_vote( simple_dvt = get_simple_dvt() staking_router = get_staking_router() easy_track = get_easy_track() + nor = get_nor() # Before voting tests # 1) Locator @@ -270,6 +274,7 @@ def test_vote( # Check APM Node Operators Registry app repo has OLD_NOR_IMPL before vote # version set to 4, Content URI without changes assert_repo_before_vote(nor_old_app, 4, OLD_NOR_IMPL, NOR_URI) + assert nor.getContractVersion() == OLD_NOR_VERSION # SDVT # 10)-12) sdvt_app_repo = interface.Repo(SIMPLE_DVT_REPO) @@ -279,6 +284,7 @@ def test_vote( # Check SimpleDVT app Repo repo has OLD_SDVT_IMPL before vote # version set to 1, Content URI without changes assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, SDVT_URI) + assert simple_dvt.getContractVersion() == OLD_SDVT_VERSION # AO # 13) Check implementation check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) @@ -365,6 +371,7 @@ def test_vote( # version set to 5, Content URI without changes nor_new_app = nor_app_repo.getLatest() assert_repo_update(nor_new_app, nor_old_app, NEW_NODE_OPERATORS_REGISTRY_IMPL, NOR_URI) + assert nor.getContractVersion() == NOR_VERSION # SDVT # 10)-12) # Check implementation address after vote @@ -373,6 +380,7 @@ def test_vote( # version set to 2, Content URI without changes sdvt_new_app = sdvt_app_repo.getLatest() assert_repo_update(sdvt_new_app, sdvt_old_app, NEW_SIMPLE_DVT_IMPL, SDVT_URI) + assert simple_dvt.getContractVersion() == SDVT_VERSION # AO # 13) check_ossifiable_proxy_impl(ao_proxy, NEW_ACCOUNTING_ORACLE_IMPL) @@ -566,6 +574,10 @@ def get_simple_dvt(): return interface.SimpleDVT(SIMPLE_DVT) +def get_nor(): + return interface.NodeOperatorsRegistry(NODE_OPERATORS_REGISTRY) + + def get_burner(): return interface.Burner(BURNER) From 8c63308cf6af79b279dfb6528044183e52fffcca Mon Sep 17 00:00:00 2001 From: skhomuti Date: Mon, 21 Oct 2024 18:06:37 +0500 Subject: [PATCH 201/220] fix accounting tests not preparing csm depositable keys if there is an operator but with no deposited keys --- tests/regression/test_accounting.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/regression/test_accounting.py b/tests/regression/test_accounting.py index 202a83fe0..f0394c1c5 100644 --- a/tests/regression/test_accounting.py +++ b/tests/regression/test_accounting.py @@ -1086,13 +1086,14 @@ def _fill_csm_module_if_empty(): staking_modules = contracts.staking_router.getAllStakingModuleDigests() assert len(staking_modules) == 3, "Modules count mismatch" - def operators_count(digest): - return digest[0] + def active_keys_count(digest): + # total deposited - total exited + return digest[3][1] - digest[3][0] - assert operators_count(staking_modules[0]) > 0, "NOR module empty" - assert operators_count(staking_modules[1]) > 0, "Simple DVT module empty" + assert active_keys_count(staking_modules[0]) > 0, "NOR module empty" + assert active_keys_count(staking_modules[1]) > 0, "Simple DVT module empty" - if operators_count(staking_modules[2]) == 0: + if active_keys_count(staking_modules[2]) == 0: keys_count = 5 address, proof = get_ea_member() csm_add_node_operator(contracts.csm, contracts.cs_accounting, address, proof, keys_count) From e2274f82a96193785b900e5e42bd52914bbdfac5 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Mon, 21 Oct 2024 18:25:40 +0400 Subject: [PATCH 202/220] docs: update vote description --- scripts/upgrade_sr_v2.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index b9b72fcf4..be59296d9 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -148,6 +148,10 @@ [Staking Router 2.0 upgrade](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Staking%20Router%20v2%20Report%2010-24.pdf), [CSM](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Community%20Staking%20Module%20Report%2010-24.pdf) both with deployment verification by Ackee Blockchain; [Staking Router 2.0 & CSM](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20CSM%20Security%20Audit%20Report%2010-24.pdf), [Lido Oracle](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Oracle%20Security%20Audit%20Report%2010-24.pdf) (incl. CSM Oracle) by Mixbytes; The AccountingOracle (negative rebase parameters, pluggable second opinion) was part of Staking Router 2.0 upgrade audits and also audited separately: [Mixbytes report](https://github.com/lidofinance/audits/blob/main/Lido%20Sanity%20Checker%20Security%20Audit%20Report.pdf) and [ChainSecurity report](https://github.com/lidofinance/audits/blob/main/ChainSecurity%20Code%20Assessment%20of%20LIP-23%20Negative%20Rebase%20Checks%20Smart%20Contracts%2006-24.pdf). + +Additionally, separate from the Staking Router 2.0 and CSM Release: + +3. **Rotate the Instadapp Oracle address**, [as requested on the forum](https://research.lido.fi/t/expansion-of-lidos-ethereum-oracle-set/2836/71). Items 27-33. """ From 8b814d5ee441840eefb51e9fd8ad002b1b93fd91 Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Mon, 21 Oct 2024 19:19:15 +0400 Subject: [PATCH 203/220] docs: update items --- scripts/upgrade_sr_v2.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/scripts/upgrade_sr_v2.py b/scripts/upgrade_sr_v2.py index be59296d9..9297ada4b 100644 --- a/scripts/upgrade_sr_v2.py +++ b/scripts/upgrade_sr_v2.py @@ -140,13 +140,10 @@ description = """ Release the Community Staking Module (CSM) for permissionless staking and upgrade the Staking Router to ensure compatibility with CSM and future modules, improving system efficiency. A detailed action plan can be found [on the research forum](https://research.lido.fi/t/staking-router-community-staking-module-upgrade-announcement/8612/6). -1. **Staking Router and related contracts upgrade** following the DAO-approved [LIP-25: Staking Router 2.0](https://snapshot.org/#/lido-snapshot.eth/proposal/0xffb4042d3bfceef33c66f78c092a76fa8e1db198559d93798cc9db3fb4d722e7) and [LIP-23: Negative rebase sanity check with a pluggable second opinion](https://snapshot.org/#/lido-snapshot.eth/proposal/0xa44f6a4dba07d7e24b0e4180025f7a9db6251046daa74d2a8fae84de0d9ce21e) designs. - -2. **Add Community Staking Module** to the Staking Router. CSM follows the [approved LIP-26 design and Mainnet Release Setup](https://snapshot.org/#/lido-snapshot.eth/proposal/0xd0d7bfd68f2241524dbb14ae6fe0e8414b9fe3e0dcfc50641a8d28f0067d6693). - -**Audits:** -[Staking Router 2.0 upgrade](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Staking%20Router%20v2%20Report%2010-24.pdf), [CSM](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Community%20Staking%20Module%20Report%2010-24.pdf) both with deployment verification by Ackee Blockchain; [Staking Router 2.0 & CSM](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20CSM%20Security%20Audit%20Report%2010-24.pdf), [Lido Oracle](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Oracle%20Security%20Audit%20Report%2010-24.pdf) (incl. CSM Oracle) by Mixbytes; +1. **Staking Router and related contracts upgrade** following the DAO-approved [LIP-25: Staking Router 2.0](https://snapshot.org/#/lido-snapshot.eth/proposal/0xffb4042d3bfceef33c66f78c092a76fa8e1db198559d93798cc9db3fb4d722e7) and [LIP-23: Negative rebase sanity check with a pluggable second opinion](https://snapshot.org/#/lido-snapshot.eth/proposal/0xa44f6a4dba07d7e24b0e4180025f7a9db6251046daa74d2a8fae84de0d9ce21e) designs. Items 1-19. +2. **Add Community Staking Module** to the Staking Router. CSM follows the [approved LIP-26 design and Mainnet Release Setup](https://snapshot.org/#/lido-snapshot.eth/proposal/0xd0d7bfd68f2241524dbb14ae6fe0e8414b9fe3e0dcfc50641a8d28f0067d6693). Items 20-26. +**Audits:** [Staking Router 2.0 upgrade](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Staking%20Router%20v2%20Report%2010-24.pdf), [CSM](https://github.com/lidofinance/audits/blob/main/Ackee%20Blockchain%20Lido%20Community%20Staking%20Module%20Report%2010-24.pdf) both with deployment verification by Ackee Blockchain; [Staking Router 2.0 & CSM](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20CSM%20Security%20Audit%20Report%2010-24.pdf), [Lido Oracle](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Oracle%20Security%20Audit%20Report%2010-24.pdf) (incl. CSM Oracle) by Mixbytes; The AccountingOracle (negative rebase parameters, pluggable second opinion) was part of Staking Router 2.0 upgrade audits and also audited separately: [Mixbytes report](https://github.com/lidofinance/audits/blob/main/Lido%20Sanity%20Checker%20Security%20Audit%20Report.pdf) and [ChainSecurity report](https://github.com/lidofinance/audits/blob/main/ChainSecurity%20Code%20Assessment%20of%20LIP-23%20Negative%20Rebase%20Checks%20Smart%20Contracts%2006-24.pdf). Additionally, separate from the Staking Router 2.0 and CSM Release: From ad488bb362d0d717a51c43a66c9a8643a93eae30 Mon Sep 17 00:00:00 2001 From: maksim Date: Wed, 23 Oct 2024 11:16:58 +0200 Subject: [PATCH 204/220] move vote script and tests to archive --- .../scripts/upgrade_2024_10_22.py | 0 archive/tests/test_upgrade_2024_10_22.py | 876 ++++++++++++++++++ 2 files changed, 876 insertions(+) rename scripts/upgrade_sr_v2.py => archive/scripts/upgrade_2024_10_22.py (100%) create mode 100644 archive/tests/test_upgrade_2024_10_22.py diff --git a/scripts/upgrade_sr_v2.py b/archive/scripts/upgrade_2024_10_22.py similarity index 100% rename from scripts/upgrade_sr_v2.py rename to archive/scripts/upgrade_2024_10_22.py diff --git a/archive/tests/test_upgrade_2024_10_22.py b/archive/tests/test_upgrade_2024_10_22.py new file mode 100644 index 000000000..eeb6f99e9 --- /dev/null +++ b/archive/tests/test_upgrade_2024_10_22.py @@ -0,0 +1,876 @@ +import pytest + +from scripts.upgrade_sr_v2 import start_vote +from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS +from brownie import interface, Contract +from utils.test.tx_tracing_helpers import * +from utils.test.event_validators.permission import validate_grant_role_event, validate_revoke_role_event +from utils.test.event_validators.common import validate_events_chain +from utils.test.event_validators.repo_upgrade import validate_repo_upgrade_event, RepoUpgrade +from utils.test.event_validators.aragon import validate_app_update_event +from typing import NamedTuple +from utils.test.event_validators.easy_track import ( + validate_evmscript_factory_added_event, + validate_evmscript_factory_removed_event, + EVMScriptFactoryAdded, +) +from utils.easy_track import create_permissions, create_permissions_overloaded +from utils.test.event_validators.hash_consensus import ( + validate_hash_consensus_member_removed, + validate_hash_consensus_member_added, +) + +# Addresses that will not be changed + +NODE_OPERATORS_REGISTRY = "0x55032650b14df07b85bF18A3a3eC8E0Af2e028d5" +SIMPLE_DVT = "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" +LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" +STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" +ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" +VALIDATORS_EXIT_BUS_ORACLE = "0x0De4Ea0184c2ad0BacA7183356Aea5B8d5Bf5c6e" +AGENT = "0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c" +BURNER = "0xD15a672319Cf0352560eE76d9e89eAB0889046D3" +VOTING = "0x2e59A20f205bB85a89C53f1936454680651E618e" + +HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" +HASH_CONSENSUS_FOR_VEBO = "0x7FaDB6358950c5fAA66Cb5EB8eE5147De3df355a" + +# aragon repo +NODE_OPERATORS_REGISTRY_REPO = "0x0D97E876ad14DB2b183CFeEB8aa1A5C788eB1831" +SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" + +# Addresses before vote +OLD_LOCATOR_IMPL_ADDRESS = "0x39aFE23cE59e8Ef196b81F0DCb165E9aD38b9463" +OLD_SR_IMPL_ADDRESS = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" +OLD_NOR_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" +OLD_SDVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" +OLD_ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" +DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" + +# Addresses after vote +NEW_LIDO_LOCATOR_IMPL = "0x3ABc4764f0237923d52056CFba7E9AEBf87113D3" +NEW_STAKING_ROUTER_IMPL = "0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA" +NEW_NODE_OPERATORS_REGISTRY_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" +NEW_SIMPLE_DVT_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" +NEW_ACCOUNTING_ORACLE_IMPL = "0x0e65898527E77210fB0133D00dd4C0E86Dc29bC7" +DEPOSIT_SECURITY_MODULE_V3 = "0xffa96d84def2ea035c7ab153d8b991128e3d72fd" + +# Easy track sdvt +OLD_TARGET_LIMIT_FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" +NEW_TARGET_LIMIT_FACTORY = "0x161a4552A625844c822954C5AcBac928ee0f399B" + +# CSM +CSM_ADDRESS = "0xdA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F" +CS_ACCOUNTING_ADDRESS = "0x4d72BFF1BeaC69925F8Bd12526a39BAAb069e5Da" +CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0x71093efF8D8599b5fA340D665Ad60fA7C80688e4" + +# Staking Router parameters +NOR_URI = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" +CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10_000 +CURATED_MAX_DEPOSITS_PER_BLOCK = 150 +CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 + +SDVT_URI = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" +SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 444 +SDVT_MAX_DEPOSITS_PER_BLOCK = 150 +SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 + +# Aragon app ids +NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" +SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" + +# Easytrack +EASYTRACK = "0xF0211b7660680B49De1A7E9f25C65660F0a13Fea" + + +# Accounting oracle +AO_CONSENSUS_VERSION = 2 +# Vebo +VEBO_CONSENSUS_VERSION = 2 + +# NOR +### RewardDistributionState +DISTRIBUTED = 2 + +## Contract versions +SR_VERSION = 2 +NOR_VERSION = 3 +SDVT_VERSION = 3 +AO_VERSION = 2 + +OLD_NOR_VERSION = 2 +OLD_SDVT_VERSION = 2 + +# CSM parameters + +CS_MODULE_NAME = "Community Staking" +CS_STAKE_SHARE_LIMIT = 100 +CS_PRIORITY_EXIT_SHARE_THRESHOLD = 125 +CS_STAKING_MODULE_FEE = 600 +CS_TREASURY_FEE = 400 +CS_MAX_DEPOSITS_PER_BLOCK = 30 +CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 +CS_ORACLE_INITIAL_EPOCH = 326715 + +# CSM steaking penalty factory +EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" + +# Roles +## SR +STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" +STAKING_MODULE_PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" +STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" +MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" + +## CSM +RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" +REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" +MANAGE_MEMBERS_AND_QUORUM_ROLE = "0x66a484cf1a3c6ef8dfd59d24824943d2853a29d96f34a01271efc55774452a51" + +# Oracles members +old_oracle_member_to_remove = "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d" +new_oracle_member_to_add = "0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12" + + +class StakingModuleItem(NamedTuple): + id: int + staking_module_address: str + name: str + staking_module_fee: int + stake_share_limit: int + treasury_fee: int + priority_exit_share_threshold: int + max_deposits_per_block: int + min_deposit_block_distance: int + + +CURATED_MODULE_BEFORE_VOTE = { + "id": 1, + "name": "curated-onchain-v1", + "stakingModuleAddress": NODE_OPERATORS_REGISTRY, + "stakingModuleFee": 500, + "treasuryFee": 500, + "targetShare": 10000, + "priorityExitShareThreshold": None, + "maxDepositsPerBlock": None, + "minDepositBlockDistance": None, +} + +SDVT_MODULE_BEFORE_VOTE = { + "id": 2, + "name": "SimpleDVT", + "stakingModuleAddress": SIMPLE_DVT, + "stakingModuleFee": 800, + "treasuryFee": 200, + "targetShare": 400, + "priorityExitShareThreshold": None, + "maxDepositsPerBlock": None, + "minDepositBlockDistance": None, +} + +CURATED_MODULE_AFTER_VOTE = CURATED_MODULE_BEFORE_VOTE.copy() +CURATED_MODULE_AFTER_VOTE.update( + { + "priorityExitShareThreshold": CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, + "maxDepositsPerBlock": CURATED_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, + } +) + +SDVT_MODULE_AFTER_VOTE = SDVT_MODULE_BEFORE_VOTE.copy() +SDVT_MODULE_AFTER_VOTE.update( + { + "priorityExitShareThreshold": SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS, + "maxDepositsPerBlock": SDVT_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": SDVT_MIN_DEPOSIT_BLOCK_DISTANCES, + } +) + +CSM_AFTER_VOTE = { + "id": 3, + "name": CS_MODULE_NAME, + "stakingModuleAddress": CSM_ADDRESS, + "stakingModuleFee": CS_STAKING_MODULE_FEE, + "treasuryFee": CS_TREASURY_FEE, + "targetShare": CS_STAKE_SHARE_LIMIT, + "priorityExitShareThreshold": CS_PRIORITY_EXIT_SHARE_THRESHOLD, + "maxDepositsPerBlock": CS_MAX_DEPOSITS_PER_BLOCK, + "minDepositBlockDistance": CS_MIN_DEPOSIT_BLOCK_DISTANCE, +} + +OLD_SR_ABI = [ + { + "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], + "name": "getStakingModule", + "outputs": [ + { + "components": [ + {"internalType": "uint24", "name": "id", "type": "uint24"}, + {"internalType": "address", "name": "stakingModuleAddress", "type": "address"}, + {"internalType": "uint16", "name": "stakingModuleFee", "type": "uint16"}, + {"internalType": "uint16", "name": "treasuryFee", "type": "uint16"}, + {"internalType": "uint16", "name": "stakeShareLimit", "type": "uint16"}, + {"internalType": "uint8", "name": "status", "type": "uint8"}, + {"internalType": "string", "name": "name", "type": "string"}, + {"internalType": "uint64", "name": "lastDepositAt", "type": "uint64"}, + {"internalType": "uint256", "name": "lastDepositBlock", "type": "uint256"}, + {"internalType": "uint256", "name": "exitedValidatorsCount", "type": "uint256"}, + ], + "internalType": "struct StakingRouter.StakingModule", + "name": "", + "type": "tuple", + } + ], + "stateMutability": "view", + "type": "function", + } +] + + +def test_vote( + helpers, + accounts, + vote_ids_from_env, +): + sr_proxy = interface.OssifiableProxy(STAKING_ROUTER) + locator_proxy = interface.OssifiableProxy(LIDO_LOCATOR) + nor_proxy = interface.AppProxyUpgradeable(NODE_OPERATORS_REGISTRY) + sdvt_proxy = interface.AppProxyUpgradeable(SIMPLE_DVT) + ao_proxy = interface.OssifiableProxy(ACCOUNTING_ORACLE) + vebo = get_vebo() + burner = get_burner() + csm = get_csm() + csm_hash_consensus = get_csm_hash_consensus() + ao = get_ao() + simple_dvt = get_simple_dvt() + staking_router = get_staking_router() + easy_track = get_easy_track() + nor = get_nor() + + # Before voting tests + # 1) Locator + # Check implementation address before vote + check_ossifiable_proxy_impl(locator_proxy, OLD_LOCATOR_IMPL_ADDRESS) + # DSM + # 2)-3) Check old DSM has STAKING_MODULE_PAUSE_ROLE, STAKING_MODULE_RESUME_ROLE + # 4) Check new DSM doesn't have STAKING_MODULE_UNVETTING_ROLE + check_dsm_roles_before_vote() + # SR + # 5) Check implementation address before vote + check_ossifiable_proxy_impl(sr_proxy, OLD_SR_IMPL_ADDRESS) + # 6) Check Curated, SDVT modules before vote + # id, name, stakingModuleAddress, stakingModuleFee, treasuryFee, targetShare - match corresponding values in CURATED_MODULE_BEFORE_VOTE, SDVT_MODULE_BEFORE_VOTE + # priorityExitShareThreshold, maxDepositsPerBlock, minDepositBlockDistance - no values in SR yet + check_module_before_vote(CURATED_MODULE_BEFORE_VOTE) + check_module_before_vote(SDVT_MODULE_BEFORE_VOTE) + # Version + assert staking_router.getContractVersion() == 1 + # NOR + # 7)-9) + nor_app_repo = interface.Repo(NODE_OPERATORS_REGISTRY_REPO) + # Check implementation address before vote + assert nor_proxy.implementation() == OLD_NOR_IMPL + nor_old_app = nor_app_repo.getLatest() + # Check APM Node Operators Registry app repo has OLD_NOR_IMPL before vote + # version set to 4, Content URI without changes + assert_repo_before_vote(nor_old_app, 4, OLD_NOR_IMPL, NOR_URI) + assert nor.getContractVersion() == OLD_NOR_VERSION + # SDVT + # 10)-12) + sdvt_app_repo = interface.Repo(SIMPLE_DVT_REPO) + # Check implementation address before vote + assert sdvt_proxy.implementation() == OLD_SDVT_IMPL + sdvt_old_app = sdvt_app_repo.getLatest() + # Check SimpleDVT app Repo repo has OLD_SDVT_IMPL before vote + # version set to 1, Content URI without changes + assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, SDVT_URI) + assert simple_dvt.getContractVersion() == OLD_SDVT_VERSION + # AO + # 13) Check implementation + check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) + # 14) Check AO contract version + assert ao.getContractVersion() == 1 + assert ao.getConsensusVersion() == 1 + + # VEBO + # 15), 17) Aragon Agent does not have MANAGE_CONSENSUS_VERSION_ROLE role + check_vebo_doesnt_have_manage_consensus_role() + # 16) Check consensus version + assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 + # 18)-19) simple dvt has old factory + evm_script_factories_before = easy_track.getEVMScriptFactories() + assert OLD_TARGET_LIMIT_FACTORY in evm_script_factories_before + assert NEW_TARGET_LIMIT_FACTORY not in evm_script_factories_before + # 20) Two modules in SR + assert staking_router.getStakingModulesCount() == 2 + # 21) CSAccounting doesnt have burn role + assert not burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + # 22), 24) Aragon Agent doesnt have resume role + assert not csm.hasRole(RESUME_ROLE, AGENT) + # 23) CSM is on pause + assert csm.isPaused() + # 25) epoch is set to far future epoch + assert csm_hash_consensus.getFrameConfig()[0] == 48038396021100853 + # 26) no factory for csm yet + assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY not in evm_script_factories_before + + # 27), 31) before vote old member is still in the quorum of ao hash consensus, new member is not in the quorum + ao_hash_consensus = get_ao_hash_consensus() + assert ao_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert not ao_hash_consensus.getIsMember(new_oracle_member_to_add) + assert ao_hash_consensus.getQuorum() == 5 + # 28), 32) before vote old member is still in the quorum of vebo hash consensus, new member is not in the quorum + vebo_hash_consensus = get_vebo_hash_consensus() + assert vebo_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert not vebo_hash_consensus.getIsMember(new_oracle_member_to_add) + assert vebo_hash_consensus.getQuorum() == 5 + + # 29) agent doesnt have role + assert not csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) + + # 30), 33) before vote old member is still in the quorum of cs hash consensus, new member is not in the quorum + assert csm_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert not csm_hash_consensus.getIsMember(new_oracle_member_to_add) + assert csm_hash_consensus.getQuorum() == 5 + + # START VOTE + if len(vote_ids_from_env) > 0: + (vote_id,) = vote_ids_from_env + else: + tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS} + vote_id, _ = start_vote(tx_params, silent=True) + + voting = get_voting() + + vote_tx = helpers.execute_vote(accounts, vote_id, voting) + + print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") + + # 1) Locator + # Check implementation address after vote + check_ossifiable_proxy_impl(locator_proxy, NEW_LIDO_LOCATOR_IMPL) + # 2)-4) DSM + # Check old dsm doesnt have STAKING_MODULE_PAUSE_ROLE, STAKING_MODULE_RESUME_ROLE + # Check new dsm has STAKING_MODULE_UNVETTING_ROLE + check_dsm_roles_after_vote() + # SR + # 5) implementation update + check_ossifiable_proxy_impl(sr_proxy, NEW_STAKING_ROUTER_IMPL) + # 6) + # finalizeUpgrade_v2 + # Store the maxDepositsPerBlock, minDepositBlockDistance, priorityExitShareThreshold for Curated, Simple DVT modules in the Staking Router's state + check_module_after_vote(CURATED_MODULE_AFTER_VOTE) + check_module_after_vote(SDVT_MODULE_AFTER_VOTE) + # This also updates the contract version to 2 + assert staking_router.getContractVersion() == 2 + # NOR + # 7)-9) + # Check implementation address after vote + assert nor_proxy.implementation() == NEW_NODE_OPERATORS_REGISTRY_IMPL + # Check APM Node Operators Registry app repo has NEW_NOR_IMPL after vote + # version set to 5, Content URI without changes + nor_new_app = nor_app_repo.getLatest() + assert_repo_update(nor_new_app, nor_old_app, NEW_NODE_OPERATORS_REGISTRY_IMPL, NOR_URI) + assert nor.getContractVersion() == NOR_VERSION + # SDVT + # 10)-12) + # Check implementation address after vote + assert sdvt_proxy.implementation() == NEW_SIMPLE_DVT_IMPL + # Check SimpleDVT app Repo repo has NEW_SDVT_IMPL before vote + # version set to 2, Content URI without changes + sdvt_new_app = sdvt_app_repo.getLatest() + assert_repo_update(sdvt_new_app, sdvt_old_app, NEW_SIMPLE_DVT_IMPL, SDVT_URI) + assert simple_dvt.getContractVersion() == SDVT_VERSION + # AO + # 13) + check_ossifiable_proxy_impl(ao_proxy, NEW_ACCOUNTING_ORACLE_IMPL) + # 14) Check AO contract version + assert ao.getContractVersion() == 2 + assert ao.getConsensusVersion() == 2 + # 15), 17) + # no permission to manage consensus version on agent + check_vebo_doesnt_have_manage_consensus_role() + # 16) + # VEBO consensus version + assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION + + # 18)-19) simple dvt has new factory + evm_script_factories_after = easy_track.getEVMScriptFactories() + assert OLD_TARGET_LIMIT_FACTORY not in evm_script_factories_after + assert NEW_TARGET_LIMIT_FACTORY in evm_script_factories_after + # 20) Three modules in SR + assert staking_router.getStakingModulesCount() == 3 + check_csm() + # 21) CSAccounting has request burn role + assert burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) + # 22), 24) Aragon Agent doesn't have resume_role + assert not csm.hasRole(RESUME_ROLE, AGENT) + # 23) CSM is not on pause + assert not csm.isPaused() + # 25) Check epoch + assert csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH + # 26) Factory check + assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY in evm_script_factories_after + + # 27), 31) after vote old member is not in the quorum of ao hash consensus, new member is in the quorum + assert not ao_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert ao_hash_consensus.getIsMember(new_oracle_member_to_add) + assert ao_hash_consensus.getQuorum() == 5 + # 28), 32) after vote old member is not in the quorum of vebo hash consensus, new member is in the quorum + vebo_hash_consensus = get_vebo_hash_consensus() + assert not vebo_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert vebo_hash_consensus.getIsMember(new_oracle_member_to_add) + assert vebo_hash_consensus.getQuorum() == 5 + + # 29) agent doesnt have role + assert csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) + + # 30), 33) after vote old member is not in the quorum of cs hash consensus, new member is in the quorum + assert not csm_hash_consensus.getIsMember(old_oracle_member_to_remove) + assert csm_hash_consensus.getIsMember(new_oracle_member_to_add) + assert csm_hash_consensus.getQuorum() == 5 + + # Events check + display_voting_events(vote_tx) + events = group_voting_events(vote_tx) + + assert len(events) == 33 + + validate_upgrade_events(events[0], NEW_LIDO_LOCATOR_IMPL) + validate_dsm_roles_events(events) + validate_upgrade_events(events[4], NEW_STAKING_ROUTER_IMPL) + + validate_staking_module_update( + events[5], + [ + StakingModuleItem( + CURATED_MODULE_AFTER_VOTE["id"], + CURATED_MODULE_AFTER_VOTE["stakingModuleAddress"], + CURATED_MODULE_AFTER_VOTE["name"], + CURATED_MODULE_AFTER_VOTE["stakingModuleFee"], + CURATED_MODULE_AFTER_VOTE["targetShare"], + CURATED_MODULE_AFTER_VOTE["treasuryFee"], + CURATED_MODULE_AFTER_VOTE["priorityExitShareThreshold"], + CURATED_MODULE_AFTER_VOTE["maxDepositsPerBlock"], + CURATED_MODULE_AFTER_VOTE["minDepositBlockDistance"], + ), + StakingModuleItem( + SDVT_MODULE_AFTER_VOTE["id"], + SDVT_MODULE_AFTER_VOTE["stakingModuleAddress"], + SDVT_MODULE_AFTER_VOTE["name"], + SDVT_MODULE_AFTER_VOTE["stakingModuleFee"], + SDVT_MODULE_AFTER_VOTE["targetShare"], + SDVT_MODULE_AFTER_VOTE["treasuryFee"], + SDVT_MODULE_AFTER_VOTE["priorityExitShareThreshold"], + SDVT_MODULE_AFTER_VOTE["maxDepositsPerBlock"], + SDVT_MODULE_AFTER_VOTE["minDepositBlockDistance"], + ), + ], + ) + + validate_repo_upgrade_event(events[6], RepoUpgrade(6, nor_new_app[0])) + validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NEW_NODE_OPERATORS_REGISTRY_IMPL) + validate_nor_update(events[8], NOR_VERSION) + + validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) + validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, NEW_SIMPLE_DVT_IMPL) + validate_nor_update(events[11], SDVT_VERSION) + + # AO + validate_upgrade_events(events[12], NEW_ACCOUNTING_ORACLE_IMPL) + validate_ao_update(events[13], AO_VERSION, AO_CONSENSUS_VERSION) + + validate_grant_role_event(events[14], MANAGE_CONSENSUS_VERSION_ROLE, AGENT, AGENT) + + validate_vebo_consensus_version_set(events[15]) + + validate_revoke_role_event(events[16], MANAGE_CONSENSUS_VERSION_ROLE, AGENT, AGENT) + + validate_evmscript_factory_removed_event(events[17], OLD_TARGET_LIMIT_FACTORY) + + simple_dvt = get_simple_dvt() + + validate_evmscript_factory_added_event( + events[18], + EVMScriptFactoryAdded( + factory_addr=NEW_TARGET_LIMIT_FACTORY, + permissions=( + create_permissions_overloaded(simple_dvt, "updateTargetValidatorsLimits", "uint256,uint256,uint256") + ), + ), + ) + + validate_module_add( + events[19], + StakingModuleItem( + CSM_AFTER_VOTE["id"], + CSM_AFTER_VOTE["stakingModuleAddress"], + CSM_AFTER_VOTE["name"], + CSM_AFTER_VOTE["stakingModuleFee"], + CSM_AFTER_VOTE["targetShare"], + CSM_AFTER_VOTE["treasuryFee"], + CSM_AFTER_VOTE["priorityExitShareThreshold"], + CSM_AFTER_VOTE["maxDepositsPerBlock"], + CSM_AFTER_VOTE["minDepositBlockDistance"], + ), + ) + validate_grant_role_event(events[20], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, AGENT) + validate_grant_role_event(events[21], RESUME_ROLE, AGENT, AGENT) + + validate_resume_event(events[22]) + validate_revoke_role_event(events[23], RESUME_ROLE, AGENT, AGENT) + validate_updateInitial_epoch(events[24]) + + validate_evmscript_factory_added_event( + events[25], + EVMScriptFactoryAdded( + factory_addr=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, + permissions=(create_permissions(csm, "settleELRewardsStealingPenalty")), + ), + ["LogScriptCall", "EVMScriptFactoryAdded", "ScriptResult", "ExecuteVote"], + ) + + validate_hash_consensus_member_removed(events[26], old_oracle_member_to_remove, 5, new_total_members=8) + validate_hash_consensus_member_removed(events[27], old_oracle_member_to_remove, 5, new_total_members=8) + validate_grant_role_event(events[28], MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT, AGENT) + validate_hash_consensus_member_removed( + events[29], + old_oracle_member_to_remove, + 5, + new_total_members=8, + ) + validate_hash_consensus_member_added(events[30], new_oracle_member_to_add, 5, new_total_members=9) + validate_hash_consensus_member_added( + events[31], + new_oracle_member_to_add, + 5, + new_total_members=9, + ) + validate_hash_consensus_member_added( + events[32], + new_oracle_member_to_add, + 5, + new_total_members=9, + ) + + +def get_staking_router(): + return interface.StakingRouter(STAKING_ROUTER) + + +def get_deposit_security_module_v3(): + return interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE_V3) + + +def get_deposit_security_module_v2(): + return interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE_V2) + + +def get_vebo(): + return interface.ValidatorsExitBusOracle(VALIDATORS_EXIT_BUS_ORACLE) + + +def get_simple_dvt(): + return interface.SimpleDVT(SIMPLE_DVT) + + +def get_nor(): + return interface.NodeOperatorsRegistry(NODE_OPERATORS_REGISTRY) + + +def get_burner(): + return interface.Burner(BURNER) + + +def get_csm(): + return interface.CSModule(CSM_ADDRESS) + + +def get_voting(): + return interface.Voting(VOTING) + + +def get_csm_hash_consensus(): + return interface.CSHashConsensus(CS_ORACLE_HASH_CONSENSUS_ADDRESS) + + +def get_ao(): + return interface.AccountingOracle(ACCOUNTING_ORACLE) + + +def get_easy_track(): + return interface.EasyTrack(EASYTRACK) + + +def get_ao_hash_consensus(): + return interface.HashConsensus(HASH_CONSENSUS_FOR_AO) + + +def get_vebo_hash_consensus(): + return interface.HashConsensus(HASH_CONSENSUS_FOR_VEBO) + + +def check_ossifiable_proxy_impl(proxy, expected_impl): + current_impl_address = proxy.proxy__getImplementation() + assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" + + +def check_dsm_roles_before_vote(): + staking_router = get_staking_router() + deposit_security_module_v2 = get_deposit_security_module_v2() + deposit_security_module_v3 = get_deposit_security_module_v3() + new_dsm_has_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) + assert not new_dsm_has_unvet_role + + old_dsm_has_pause_role = staking_router.hasRole(STAKING_MODULE_PAUSE_ROLE, deposit_security_module_v2) + + assert old_dsm_has_pause_role + + old_dsm_has_resume_role = staking_router.hasRole(STAKING_MODULE_RESUME_ROLE, deposit_security_module_v2) + + assert old_dsm_has_resume_role + + +def check_dsm_roles_after_vote(): + staking_router = get_staking_router() + deposit_security_module_v2 = get_deposit_security_module_v2() + deposit_security_module_v3 = get_deposit_security_module_v3() + new_dsm_has_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) + assert new_dsm_has_unvet_role + + old_dsm_has_pause_role = staking_router.hasRole(STAKING_MODULE_PAUSE_ROLE, deposit_security_module_v2) + assert not old_dsm_has_pause_role + + old_dsm_has_resume_role = staking_router.hasRole(STAKING_MODULE_RESUME_ROLE, deposit_security_module_v2) + assert not old_dsm_has_resume_role + + +def check_vebo_doesnt_have_manage_consensus_role(): + vebo = get_vebo() + agent_has_manage_consensus_role = vebo.hasRole(MANAGE_CONSENSUS_VERSION_ROLE, AGENT) + assert not agent_has_manage_consensus_role + + +def check_module_before_vote(expected_module_data: Dict): + staking_router = Contract.from_abi("StakingContract", STAKING_ROUTER, OLD_SR_ABI) + module = staking_router.getStakingModule(expected_module_data["id"]) + assert module["id"] == expected_module_data["id"] + assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] + assert module["treasuryFee"] == expected_module_data["treasuryFee"] + assert module["stakeShareLimit"] == expected_module_data["targetShare"] + assert "priorityExitShareThreshold" not in module + assert "maxDepositsPerBlock" not in module + assert "minDepositBlockDistance" not in module + + +def check_module_after_vote(expected_module_data: Dict): + staking_router = get_staking_router() + module = staking_router.getStakingModule(expected_module_data["id"]) + assert module["id"] == expected_module_data["id"] + assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] + assert module["treasuryFee"] == expected_module_data["treasuryFee"] + assert module["stakeShareLimit"] == expected_module_data["targetShare"] + assert module["priorityExitShareThreshold"] == expected_module_data["priorityExitShareThreshold"] + assert module["maxDepositsPerBlock"] == expected_module_data["maxDepositsPerBlock"] + assert module["minDepositBlockDistance"] == expected_module_data["minDepositBlockDistance"] + + +def assert_repo_before_vote(old_app, version, contract_address, old_content_uri): + assert old_app[0][0] == version + assert old_app[2] == old_content_uri, "Content uri before vote is wrong" + assert old_app[1] == contract_address, "New address should match" + + +def assert_repo_update(new_app, old_app, contract_address, old_content_uri): + assert old_app[1] != new_app[1], "Address should change" + assert new_app[1] == contract_address, "New address should match" + assert new_app[0][0] == old_app[0][0] + 1, "Major version should increment" + assert old_app[2] == new_app[2], "Content uri should not be changed" + assert new_app[2] == old_content_uri, "Content uri should match" + + +# Events check + + +def validate_upgrade_events(events: EventDict, implementation: str): + _events_chain = ["LogScriptCall", "LogScriptCall", "Upgraded", "ScriptResult"] + validate_events_chain([e.name for e in events], _events_chain) + assert events.count("Upgraded") == 1 + assert events["Upgraded"]["implementation"] == implementation, "Wrong proxy implementation address" + + +def validate_dsm_roles_events(events: list[EventDict]): + validate_revoke_role_event( + events[1], + STAKING_MODULE_PAUSE_ROLE, + DEPOSIT_SECURITY_MODULE_V2, + AGENT, + ) + validate_revoke_role_event( + events[2], + STAKING_MODULE_RESUME_ROLE, + DEPOSIT_SECURITY_MODULE_V2, + AGENT, + ) + + validate_grant_role_event( + events[3], + STAKING_MODULE_UNVETTING_ROLE, + DEPOSIT_SECURITY_MODULE_V3, + AGENT, + ) + + +def validate_staking_module_update(event: EventDict, module_items: List[StakingModuleItem]): + assert len(module_items) == 2 + + _events_chain = [ + "LogScriptCall", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ContractVersionSet", + ] + + validate_events_chain([e.name for e in event], _events_chain) + + assert event.count("StakingModuleFeesSet") == 2 + assert event.count("StakingModuleShareLimitSet") == 2 + assert event.count("StakingModuleMinDepositBlockDistanceSet") == 2 + assert event.count("StakingModuleMaxDepositsPerBlockSet") == 2 + assert event.count("ContractVersionSet") == 1 + + # curated + assert event["StakingModuleShareLimitSet"][0]["stakingModuleId"] == module_items[0].id + assert event["StakingModuleShareLimitSet"][0]["stakeShareLimit"] == module_items[0].stake_share_limit + assert ( + event["StakingModuleShareLimitSet"][0]["priorityExitShareThreshold"] + == module_items[0].priority_exit_share_threshold + ) + assert event["StakingModuleFeesSet"][0]["stakingModuleId"] == module_items[0].id + assert event["StakingModuleFeesSet"][0]["stakingModuleFee"] == module_items[0].staking_module_fee + assert event["StakingModuleFeesSet"][0]["treasuryFee"] == module_items[0].treasury_fee + + assert ( + event["StakingModuleMaxDepositsPerBlockSet"][0]["maxDepositsPerBlock"] == module_items[0].max_deposits_per_block + ) + + assert ( + event["StakingModuleMinDepositBlockDistanceSet"][0]["minDepositBlockDistance"] + == module_items[0].min_deposit_block_distance + ) + + assert event["ContractVersionSet"]["version"] == SR_VERSION + + assert event["StakingModuleShareLimitSet"][1]["stakingModuleId"] == module_items[1].id + assert event["StakingModuleShareLimitSet"][1]["stakeShareLimit"] == module_items[1].stake_share_limit + assert ( + event["StakingModuleShareLimitSet"][1]["priorityExitShareThreshold"] + == module_items[1].priority_exit_share_threshold + ) + assert event["StakingModuleFeesSet"][1]["stakingModuleId"] == module_items[1].id + assert event["StakingModuleFeesSet"][1]["stakingModuleFee"] == module_items[1].staking_module_fee + assert event["StakingModuleFeesSet"][1]["treasuryFee"] == module_items[1].treasury_fee + + assert ( + event["StakingModuleMaxDepositsPerBlockSet"][1]["maxDepositsPerBlock"] == module_items[1].max_deposits_per_block + ) + + assert ( + event["StakingModuleMinDepositBlockDistanceSet"][1]["minDepositBlockDistance"] + == module_items[1].min_deposit_block_distance + ) + + +def validate_nor_update(event: EventDict, version): + _events_chain = [ + "LogScriptCall", + "ContractVersionSet", + "RewardDistributionStateChanged", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["ContractVersionSet"]["version"] == version + assert event["RewardDistributionStateChanged"]["state"] == DISTRIBUTED + + +def validate_ao_update(event: EventDict, version, ao_consensus_version): + _events_chain = [ + "LogScriptCall", + "ContractVersionSet", + "ConsensusVersionSet", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["ContractVersionSet"]["version"] == version + assert event["ConsensusVersionSet"]["version"] == ao_consensus_version + assert event["ConsensusVersionSet"]["prevVersion"] == ao_consensus_version - 1 + + +def validate_vebo_consensus_version_set(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "ConsensusVersionSet", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event["ConsensusVersionSet"]["version"] == VEBO_CONSENSUS_VERSION + + +def validate_resume_event(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "Resumed", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event.count("Resumed") == 1 + + +def validate_updateInitial_epoch(event: EventDict): + _events_chain = ["LogScriptCall", "LogScriptCall", "FrameConfigSet", "ScriptResult"] + validate_events_chain([e.name for e in event], _events_chain) + assert event["FrameConfigSet"]["newInitialEpoch"] == CS_ORACLE_INITIAL_EPOCH + + +def validate_module_add(event, csm: StakingModuleItem): + _events_chain = [ + "LogScriptCall", + "LogScriptCall", + "StakingRouterETHDeposited", + "StakingModuleAdded", + "StakingModuleShareLimitSet", + "StakingModuleFeesSet", + "StakingModuleMaxDepositsPerBlockSet", + "StakingModuleMinDepositBlockDistanceSet", + "ScriptResult", + ] + validate_events_chain([e.name for e in event], _events_chain) + + assert event["StakingRouterETHDeposited"]["stakingModuleId"] == csm.id + assert event["StakingRouterETHDeposited"]["amount"] == 0 + assert event["StakingModuleAdded"]["stakingModuleId"] == csm.id + assert event["StakingModuleAdded"]["stakingModule"] == csm.staking_module_address + assert event["StakingModuleAdded"]["name"] == csm.name + + assert event["StakingModuleShareLimitSet"]["stakingModuleId"] == csm.id + assert event["StakingModuleShareLimitSet"]["stakeShareLimit"] == csm.stake_share_limit + assert event["StakingModuleShareLimitSet"]["priorityExitShareThreshold"] == csm.priority_exit_share_threshold + + assert event["StakingModuleFeesSet"]["stakingModuleId"] == csm.id + assert event["StakingModuleFeesSet"]["stakingModuleFee"] == csm.staking_module_fee + assert event["StakingModuleFeesSet"]["treasuryFee"] == csm.treasury_fee + + assert event["StakingModuleMaxDepositsPerBlockSet"]["maxDepositsPerBlock"] == csm.max_deposits_per_block + + assert event["StakingModuleMinDepositBlockDistanceSet"]["minDepositBlockDistance"] == csm.min_deposit_block_distance + + +def check_csm(): + staking_router = get_staking_router() + cs = staking_router.getStakingModule(3) + + assert cs["name"] == CSM_AFTER_VOTE["name"] + assert cs["stakingModuleFee"] == CSM_AFTER_VOTE["stakingModuleFee"] + assert cs["treasuryFee"] == CSM_AFTER_VOTE["treasuryFee"] + assert cs["stakeShareLimit"] == CSM_AFTER_VOTE["targetShare"] + assert cs["priorityExitShareThreshold"] == CSM_AFTER_VOTE["priorityExitShareThreshold"] + assert cs["maxDepositsPerBlock"] == CSM_AFTER_VOTE["maxDepositsPerBlock"] + assert cs["minDepositBlockDistance"] == CSM_AFTER_VOTE["minDepositBlockDistance"] From eae0ed8326c94cedb8707e66638c21d7df13ed89 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Fri, 25 Oct 2024 17:38:21 +0500 Subject: [PATCH 205/220] prefetch simple dvt contract events --- tests/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/conftest.py b/tests/conftest.py index ad0c2857f..922e22635 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -164,6 +164,7 @@ def _prefetch_contracts_from_etherscan(): Contract.from_explorer(WITHDRAWAL_QUEUE) Contract.from_explorer(STAKING_ROUTER) Contract.from_explorer(VOTING) + Contract.from_explorer(SIMPLE_DVT) Helpers._etherscan_is_fetched = True From c8e00be97f6a8ac57943d6ac06d773ee35609475 Mon Sep 17 00:00:00 2001 From: maksim Date: Fri, 25 Oct 2024 18:53:49 +0200 Subject: [PATCH 206/220] add vote execution time --- archive/scripts/upgrade_2024_10_22.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/archive/scripts/upgrade_2024_10_22.py b/archive/scripts/upgrade_2024_10_22.py index 9297ada4b..40853837d 100644 --- a/archive/scripts/upgrade_2024_10_22.py +++ b/archive/scripts/upgrade_2024_10_22.py @@ -37,6 +37,9 @@ 31. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for AccountingOracle 32. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to HashConsensus for ValidatorsExitBusOracle 33. Add oracle member with address 0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12 to CSHashConsensus for CSFeeOracle + + +Vote #180 passed & executed on Oct-25-2024 04:03:23 PM UTC, block #21043699. """ import time From 03a9f843726827fc11cf8fcf4ba5ad0e63fe92a6 Mon Sep 17 00:00:00 2001 From: maksim Date: Fri, 25 Oct 2024 19:23:21 +0200 Subject: [PATCH 207/220] clean up --- tests/test_upgrade_sr_v2.py | 876 ------------------------------------ 1 file changed, 876 deletions(-) delete mode 100644 tests/test_upgrade_sr_v2.py diff --git a/tests/test_upgrade_sr_v2.py b/tests/test_upgrade_sr_v2.py deleted file mode 100644 index eeb6f99e9..000000000 --- a/tests/test_upgrade_sr_v2.py +++ /dev/null @@ -1,876 +0,0 @@ -import pytest - -from scripts.upgrade_sr_v2 import start_vote -from utils.config import LDO_HOLDER_ADDRESS_FOR_TESTS -from brownie import interface, Contract -from utils.test.tx_tracing_helpers import * -from utils.test.event_validators.permission import validate_grant_role_event, validate_revoke_role_event -from utils.test.event_validators.common import validate_events_chain -from utils.test.event_validators.repo_upgrade import validate_repo_upgrade_event, RepoUpgrade -from utils.test.event_validators.aragon import validate_app_update_event -from typing import NamedTuple -from utils.test.event_validators.easy_track import ( - validate_evmscript_factory_added_event, - validate_evmscript_factory_removed_event, - EVMScriptFactoryAdded, -) -from utils.easy_track import create_permissions, create_permissions_overloaded -from utils.test.event_validators.hash_consensus import ( - validate_hash_consensus_member_removed, - validate_hash_consensus_member_added, -) - -# Addresses that will not be changed - -NODE_OPERATORS_REGISTRY = "0x55032650b14df07b85bF18A3a3eC8E0Af2e028d5" -SIMPLE_DVT = "0xaE7B191A31f627b4eB1d4DaC64eaB9976995b433" -LIDO_LOCATOR = "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb" -STAKING_ROUTER = "0xFdDf38947aFB03C621C71b06C9C70bce73f12999" -ACCOUNTING_ORACLE = "0x852deD011285fe67063a08005c71a85690503Cee" -VALIDATORS_EXIT_BUS_ORACLE = "0x0De4Ea0184c2ad0BacA7183356Aea5B8d5Bf5c6e" -AGENT = "0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c" -BURNER = "0xD15a672319Cf0352560eE76d9e89eAB0889046D3" -VOTING = "0x2e59A20f205bB85a89C53f1936454680651E618e" - -HASH_CONSENSUS_FOR_AO = "0xD624B08C83bAECF0807Dd2c6880C3154a5F0B288" -HASH_CONSENSUS_FOR_VEBO = "0x7FaDB6358950c5fAA66Cb5EB8eE5147De3df355a" - -# aragon repo -NODE_OPERATORS_REGISTRY_REPO = "0x0D97E876ad14DB2b183CFeEB8aa1A5C788eB1831" -SIMPLE_DVT_REPO = "0x2325b0a607808dE42D918DB07F925FFcCfBb2968" - -# Addresses before vote -OLD_LOCATOR_IMPL_ADDRESS = "0x39aFE23cE59e8Ef196b81F0DCb165E9aD38b9463" -OLD_SR_IMPL_ADDRESS = "0xD8784e748f59Ba711fB5643191Ec3fAdD50Fb6df" -OLD_NOR_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" -OLD_SDVT_IMPL = "0x8538930c385C0438A357d2c25CB3eAD95Ab6D8ed" -OLD_ACCOUNTING_ORACLE_IMPL = "0xF3c5E0A67f32CF1dc07a8817590efa102079a1aF" -DEPOSIT_SECURITY_MODULE_V2 = "0xC77F8768774E1c9244BEed705C4354f2113CFc09" - -# Addresses after vote -NEW_LIDO_LOCATOR_IMPL = "0x3ABc4764f0237923d52056CFba7E9AEBf87113D3" -NEW_STAKING_ROUTER_IMPL = "0x89eDa99C0551d4320b56F82DDE8dF2f8D2eF81aA" -NEW_NODE_OPERATORS_REGISTRY_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" -NEW_SIMPLE_DVT_IMPL = "0x1770044a38402e3CfCa2Fcfa0C84a093c9B42135" -NEW_ACCOUNTING_ORACLE_IMPL = "0x0e65898527E77210fB0133D00dd4C0E86Dc29bC7" -DEPOSIT_SECURITY_MODULE_V3 = "0xffa96d84def2ea035c7ab153d8b991128e3d72fd" - -# Easy track sdvt -OLD_TARGET_LIMIT_FACTORY = "0x41CF3DbDc939c5115823Fba1432c4EC5E7bD226C" -NEW_TARGET_LIMIT_FACTORY = "0x161a4552A625844c822954C5AcBac928ee0f399B" - -# CSM -CSM_ADDRESS = "0xdA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F" -CS_ACCOUNTING_ADDRESS = "0x4d72BFF1BeaC69925F8Bd12526a39BAAb069e5Da" -CS_ORACLE_HASH_CONSENSUS_ADDRESS = "0x71093efF8D8599b5fA340D665Ad60fA7C80688e4" - -# Staking Router parameters -NOR_URI = "0x697066733a516d54346a64693146684d454b5576575351316877786e33365748394b6a656743755a7441684a6b6368526b7a70" -CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS = 10_000 -CURATED_MAX_DEPOSITS_PER_BLOCK = 150 -CURATED_MIN_DEPOSIT_BLOCK_DISTANCES = 25 - -SDVT_URI = "0x697066733a516d615353756a484347636e4675657441504777565735426567614d42766e355343736769334c5366767261536f" -SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS = 444 -SDVT_MAX_DEPOSITS_PER_BLOCK = 150 -SDVT_MIN_DEPOSIT_BLOCK_DISTANCES = 25 - -# Aragon app ids -NODE_OPERATORS_REGISTRY_ARAGON_APP_ID = "0x7071f283424072341f856ac9e947e7ec0eb68719f757a7e785979b6b8717579d" -SIMPLE_DVT_ARAGON_APP_ID = "0xe1635b63b5f7b5e545f2a637558a4029dea7905361a2f0fc28c66e9136cf86a4" - -# Easytrack -EASYTRACK = "0xF0211b7660680B49De1A7E9f25C65660F0a13Fea" - - -# Accounting oracle -AO_CONSENSUS_VERSION = 2 -# Vebo -VEBO_CONSENSUS_VERSION = 2 - -# NOR -### RewardDistributionState -DISTRIBUTED = 2 - -## Contract versions -SR_VERSION = 2 -NOR_VERSION = 3 -SDVT_VERSION = 3 -AO_VERSION = 2 - -OLD_NOR_VERSION = 2 -OLD_SDVT_VERSION = 2 - -# CSM parameters - -CS_MODULE_NAME = "Community Staking" -CS_STAKE_SHARE_LIMIT = 100 -CS_PRIORITY_EXIT_SHARE_THRESHOLD = 125 -CS_STAKING_MODULE_FEE = 600 -CS_TREASURY_FEE = 400 -CS_MAX_DEPOSITS_PER_BLOCK = 30 -CS_MIN_DEPOSIT_BLOCK_DISTANCE = 25 -CS_ORACLE_INITIAL_EPOCH = 326715 - -# CSM steaking penalty factory -EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" - -# Roles -## SR -STAKING_MODULE_UNVETTING_ROLE = "0x240525496a9dc32284b17ce03b43e539e4bd81414634ee54395030d793463b57" -STAKING_MODULE_PAUSE_ROLE = "0x00b1e70095ba5bacc3202c3db9faf1f7873186f0ed7b6c84e80c0018dcc6e38e" -STAKING_MODULE_RESUME_ROLE = "0x9a2f67efb89489040f2c48c3b2c38f719fba1276678d2ced3bd9049fb5edc6b2" -MANAGE_CONSENSUS_VERSION_ROLE = "0xc31b1e4b732c5173dc51d519dfa432bad95550ecc4b0f9a61c2a558a2a8e4341" - -## CSM -RESUME_ROLE = "0x2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c7" -REQUEST_BURN_SHARES_ROLE = "0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8" -MANAGE_MEMBERS_AND_QUORUM_ROLE = "0x66a484cf1a3c6ef8dfd59d24824943d2853a29d96f34a01271efc55774452a51" - -# Oracles members -old_oracle_member_to_remove = "0x1Ca0fEC59b86F549e1F1184d97cb47794C8Af58d" -new_oracle_member_to_add = "0x73181107c8D9ED4ce0bbeF7A0b4ccf3320C41d12" - - -class StakingModuleItem(NamedTuple): - id: int - staking_module_address: str - name: str - staking_module_fee: int - stake_share_limit: int - treasury_fee: int - priority_exit_share_threshold: int - max_deposits_per_block: int - min_deposit_block_distance: int - - -CURATED_MODULE_BEFORE_VOTE = { - "id": 1, - "name": "curated-onchain-v1", - "stakingModuleAddress": NODE_OPERATORS_REGISTRY, - "stakingModuleFee": 500, - "treasuryFee": 500, - "targetShare": 10000, - "priorityExitShareThreshold": None, - "maxDepositsPerBlock": None, - "minDepositBlockDistance": None, -} - -SDVT_MODULE_BEFORE_VOTE = { - "id": 2, - "name": "SimpleDVT", - "stakingModuleAddress": SIMPLE_DVT, - "stakingModuleFee": 800, - "treasuryFee": 200, - "targetShare": 400, - "priorityExitShareThreshold": None, - "maxDepositsPerBlock": None, - "minDepositBlockDistance": None, -} - -CURATED_MODULE_AFTER_VOTE = CURATED_MODULE_BEFORE_VOTE.copy() -CURATED_MODULE_AFTER_VOTE.update( - { - "priorityExitShareThreshold": CURATED_PRIORITY_EXIT_SHARE_THRESHOLDS, - "maxDepositsPerBlock": CURATED_MAX_DEPOSITS_PER_BLOCK, - "minDepositBlockDistance": CURATED_MIN_DEPOSIT_BLOCK_DISTANCES, - } -) - -SDVT_MODULE_AFTER_VOTE = SDVT_MODULE_BEFORE_VOTE.copy() -SDVT_MODULE_AFTER_VOTE.update( - { - "priorityExitShareThreshold": SDVT_PRIORITY_EXIT_SHARE_THRESHOLDS, - "maxDepositsPerBlock": SDVT_MAX_DEPOSITS_PER_BLOCK, - "minDepositBlockDistance": SDVT_MIN_DEPOSIT_BLOCK_DISTANCES, - } -) - -CSM_AFTER_VOTE = { - "id": 3, - "name": CS_MODULE_NAME, - "stakingModuleAddress": CSM_ADDRESS, - "stakingModuleFee": CS_STAKING_MODULE_FEE, - "treasuryFee": CS_TREASURY_FEE, - "targetShare": CS_STAKE_SHARE_LIMIT, - "priorityExitShareThreshold": CS_PRIORITY_EXIT_SHARE_THRESHOLD, - "maxDepositsPerBlock": CS_MAX_DEPOSITS_PER_BLOCK, - "minDepositBlockDistance": CS_MIN_DEPOSIT_BLOCK_DISTANCE, -} - -OLD_SR_ABI = [ - { - "inputs": [{"internalType": "uint256", "name": "_stakingModuleId", "type": "uint256"}], - "name": "getStakingModule", - "outputs": [ - { - "components": [ - {"internalType": "uint24", "name": "id", "type": "uint24"}, - {"internalType": "address", "name": "stakingModuleAddress", "type": "address"}, - {"internalType": "uint16", "name": "stakingModuleFee", "type": "uint16"}, - {"internalType": "uint16", "name": "treasuryFee", "type": "uint16"}, - {"internalType": "uint16", "name": "stakeShareLimit", "type": "uint16"}, - {"internalType": "uint8", "name": "status", "type": "uint8"}, - {"internalType": "string", "name": "name", "type": "string"}, - {"internalType": "uint64", "name": "lastDepositAt", "type": "uint64"}, - {"internalType": "uint256", "name": "lastDepositBlock", "type": "uint256"}, - {"internalType": "uint256", "name": "exitedValidatorsCount", "type": "uint256"}, - ], - "internalType": "struct StakingRouter.StakingModule", - "name": "", - "type": "tuple", - } - ], - "stateMutability": "view", - "type": "function", - } -] - - -def test_vote( - helpers, - accounts, - vote_ids_from_env, -): - sr_proxy = interface.OssifiableProxy(STAKING_ROUTER) - locator_proxy = interface.OssifiableProxy(LIDO_LOCATOR) - nor_proxy = interface.AppProxyUpgradeable(NODE_OPERATORS_REGISTRY) - sdvt_proxy = interface.AppProxyUpgradeable(SIMPLE_DVT) - ao_proxy = interface.OssifiableProxy(ACCOUNTING_ORACLE) - vebo = get_vebo() - burner = get_burner() - csm = get_csm() - csm_hash_consensus = get_csm_hash_consensus() - ao = get_ao() - simple_dvt = get_simple_dvt() - staking_router = get_staking_router() - easy_track = get_easy_track() - nor = get_nor() - - # Before voting tests - # 1) Locator - # Check implementation address before vote - check_ossifiable_proxy_impl(locator_proxy, OLD_LOCATOR_IMPL_ADDRESS) - # DSM - # 2)-3) Check old DSM has STAKING_MODULE_PAUSE_ROLE, STAKING_MODULE_RESUME_ROLE - # 4) Check new DSM doesn't have STAKING_MODULE_UNVETTING_ROLE - check_dsm_roles_before_vote() - # SR - # 5) Check implementation address before vote - check_ossifiable_proxy_impl(sr_proxy, OLD_SR_IMPL_ADDRESS) - # 6) Check Curated, SDVT modules before vote - # id, name, stakingModuleAddress, stakingModuleFee, treasuryFee, targetShare - match corresponding values in CURATED_MODULE_BEFORE_VOTE, SDVT_MODULE_BEFORE_VOTE - # priorityExitShareThreshold, maxDepositsPerBlock, minDepositBlockDistance - no values in SR yet - check_module_before_vote(CURATED_MODULE_BEFORE_VOTE) - check_module_before_vote(SDVT_MODULE_BEFORE_VOTE) - # Version - assert staking_router.getContractVersion() == 1 - # NOR - # 7)-9) - nor_app_repo = interface.Repo(NODE_OPERATORS_REGISTRY_REPO) - # Check implementation address before vote - assert nor_proxy.implementation() == OLD_NOR_IMPL - nor_old_app = nor_app_repo.getLatest() - # Check APM Node Operators Registry app repo has OLD_NOR_IMPL before vote - # version set to 4, Content URI without changes - assert_repo_before_vote(nor_old_app, 4, OLD_NOR_IMPL, NOR_URI) - assert nor.getContractVersion() == OLD_NOR_VERSION - # SDVT - # 10)-12) - sdvt_app_repo = interface.Repo(SIMPLE_DVT_REPO) - # Check implementation address before vote - assert sdvt_proxy.implementation() == OLD_SDVT_IMPL - sdvt_old_app = sdvt_app_repo.getLatest() - # Check SimpleDVT app Repo repo has OLD_SDVT_IMPL before vote - # version set to 1, Content URI without changes - assert_repo_before_vote(sdvt_old_app, 1, OLD_SDVT_IMPL, SDVT_URI) - assert simple_dvt.getContractVersion() == OLD_SDVT_VERSION - # AO - # 13) Check implementation - check_ossifiable_proxy_impl(ao_proxy, OLD_ACCOUNTING_ORACLE_IMPL) - # 14) Check AO contract version - assert ao.getContractVersion() == 1 - assert ao.getConsensusVersion() == 1 - - # VEBO - # 15), 17) Aragon Agent does not have MANAGE_CONSENSUS_VERSION_ROLE role - check_vebo_doesnt_have_manage_consensus_role() - # 16) Check consensus version - assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION - 1 - # 18)-19) simple dvt has old factory - evm_script_factories_before = easy_track.getEVMScriptFactories() - assert OLD_TARGET_LIMIT_FACTORY in evm_script_factories_before - assert NEW_TARGET_LIMIT_FACTORY not in evm_script_factories_before - # 20) Two modules in SR - assert staking_router.getStakingModulesCount() == 2 - # 21) CSAccounting doesnt have burn role - assert not burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) - # 22), 24) Aragon Agent doesnt have resume role - assert not csm.hasRole(RESUME_ROLE, AGENT) - # 23) CSM is on pause - assert csm.isPaused() - # 25) epoch is set to far future epoch - assert csm_hash_consensus.getFrameConfig()[0] == 48038396021100853 - # 26) no factory for csm yet - assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY not in evm_script_factories_before - - # 27), 31) before vote old member is still in the quorum of ao hash consensus, new member is not in the quorum - ao_hash_consensus = get_ao_hash_consensus() - assert ao_hash_consensus.getIsMember(old_oracle_member_to_remove) - assert not ao_hash_consensus.getIsMember(new_oracle_member_to_add) - assert ao_hash_consensus.getQuorum() == 5 - # 28), 32) before vote old member is still in the quorum of vebo hash consensus, new member is not in the quorum - vebo_hash_consensus = get_vebo_hash_consensus() - assert vebo_hash_consensus.getIsMember(old_oracle_member_to_remove) - assert not vebo_hash_consensus.getIsMember(new_oracle_member_to_add) - assert vebo_hash_consensus.getQuorum() == 5 - - # 29) agent doesnt have role - assert not csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) - - # 30), 33) before vote old member is still in the quorum of cs hash consensus, new member is not in the quorum - assert csm_hash_consensus.getIsMember(old_oracle_member_to_remove) - assert not csm_hash_consensus.getIsMember(new_oracle_member_to_add) - assert csm_hash_consensus.getQuorum() == 5 - - # START VOTE - if len(vote_ids_from_env) > 0: - (vote_id,) = vote_ids_from_env - else: - tx_params = {"from": LDO_HOLDER_ADDRESS_FOR_TESTS} - vote_id, _ = start_vote(tx_params, silent=True) - - voting = get_voting() - - vote_tx = helpers.execute_vote(accounts, vote_id, voting) - - print(f"voteId = {vote_id}, gasUsed = {vote_tx.gas_used}") - - # 1) Locator - # Check implementation address after vote - check_ossifiable_proxy_impl(locator_proxy, NEW_LIDO_LOCATOR_IMPL) - # 2)-4) DSM - # Check old dsm doesnt have STAKING_MODULE_PAUSE_ROLE, STAKING_MODULE_RESUME_ROLE - # Check new dsm has STAKING_MODULE_UNVETTING_ROLE - check_dsm_roles_after_vote() - # SR - # 5) implementation update - check_ossifiable_proxy_impl(sr_proxy, NEW_STAKING_ROUTER_IMPL) - # 6) - # finalizeUpgrade_v2 - # Store the maxDepositsPerBlock, minDepositBlockDistance, priorityExitShareThreshold for Curated, Simple DVT modules in the Staking Router's state - check_module_after_vote(CURATED_MODULE_AFTER_VOTE) - check_module_after_vote(SDVT_MODULE_AFTER_VOTE) - # This also updates the contract version to 2 - assert staking_router.getContractVersion() == 2 - # NOR - # 7)-9) - # Check implementation address after vote - assert nor_proxy.implementation() == NEW_NODE_OPERATORS_REGISTRY_IMPL - # Check APM Node Operators Registry app repo has NEW_NOR_IMPL after vote - # version set to 5, Content URI without changes - nor_new_app = nor_app_repo.getLatest() - assert_repo_update(nor_new_app, nor_old_app, NEW_NODE_OPERATORS_REGISTRY_IMPL, NOR_URI) - assert nor.getContractVersion() == NOR_VERSION - # SDVT - # 10)-12) - # Check implementation address after vote - assert sdvt_proxy.implementation() == NEW_SIMPLE_DVT_IMPL - # Check SimpleDVT app Repo repo has NEW_SDVT_IMPL before vote - # version set to 2, Content URI without changes - sdvt_new_app = sdvt_app_repo.getLatest() - assert_repo_update(sdvt_new_app, sdvt_old_app, NEW_SIMPLE_DVT_IMPL, SDVT_URI) - assert simple_dvt.getContractVersion() == SDVT_VERSION - # AO - # 13) - check_ossifiable_proxy_impl(ao_proxy, NEW_ACCOUNTING_ORACLE_IMPL) - # 14) Check AO contract version - assert ao.getContractVersion() == 2 - assert ao.getConsensusVersion() == 2 - # 15), 17) - # no permission to manage consensus version on agent - check_vebo_doesnt_have_manage_consensus_role() - # 16) - # VEBO consensus version - assert vebo.getConsensusVersion() == VEBO_CONSENSUS_VERSION - - # 18)-19) simple dvt has new factory - evm_script_factories_after = easy_track.getEVMScriptFactories() - assert OLD_TARGET_LIMIT_FACTORY not in evm_script_factories_after - assert NEW_TARGET_LIMIT_FACTORY in evm_script_factories_after - # 20) Three modules in SR - assert staking_router.getStakingModulesCount() == 3 - check_csm() - # 21) CSAccounting has request burn role - assert burner.hasRole(REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS) - # 22), 24) Aragon Agent doesn't have resume_role - assert not csm.hasRole(RESUME_ROLE, AGENT) - # 23) CSM is not on pause - assert not csm.isPaused() - # 25) Check epoch - assert csm_hash_consensus.getFrameConfig()[0] == CS_ORACLE_INITIAL_EPOCH - # 26) Factory check - assert EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY in evm_script_factories_after - - # 27), 31) after vote old member is not in the quorum of ao hash consensus, new member is in the quorum - assert not ao_hash_consensus.getIsMember(old_oracle_member_to_remove) - assert ao_hash_consensus.getIsMember(new_oracle_member_to_add) - assert ao_hash_consensus.getQuorum() == 5 - # 28), 32) after vote old member is not in the quorum of vebo hash consensus, new member is in the quorum - vebo_hash_consensus = get_vebo_hash_consensus() - assert not vebo_hash_consensus.getIsMember(old_oracle_member_to_remove) - assert vebo_hash_consensus.getIsMember(new_oracle_member_to_add) - assert vebo_hash_consensus.getQuorum() == 5 - - # 29) agent doesnt have role - assert csm_hash_consensus.hasRole(MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT) - - # 30), 33) after vote old member is not in the quorum of cs hash consensus, new member is in the quorum - assert not csm_hash_consensus.getIsMember(old_oracle_member_to_remove) - assert csm_hash_consensus.getIsMember(new_oracle_member_to_add) - assert csm_hash_consensus.getQuorum() == 5 - - # Events check - display_voting_events(vote_tx) - events = group_voting_events(vote_tx) - - assert len(events) == 33 - - validate_upgrade_events(events[0], NEW_LIDO_LOCATOR_IMPL) - validate_dsm_roles_events(events) - validate_upgrade_events(events[4], NEW_STAKING_ROUTER_IMPL) - - validate_staking_module_update( - events[5], - [ - StakingModuleItem( - CURATED_MODULE_AFTER_VOTE["id"], - CURATED_MODULE_AFTER_VOTE["stakingModuleAddress"], - CURATED_MODULE_AFTER_VOTE["name"], - CURATED_MODULE_AFTER_VOTE["stakingModuleFee"], - CURATED_MODULE_AFTER_VOTE["targetShare"], - CURATED_MODULE_AFTER_VOTE["treasuryFee"], - CURATED_MODULE_AFTER_VOTE["priorityExitShareThreshold"], - CURATED_MODULE_AFTER_VOTE["maxDepositsPerBlock"], - CURATED_MODULE_AFTER_VOTE["minDepositBlockDistance"], - ), - StakingModuleItem( - SDVT_MODULE_AFTER_VOTE["id"], - SDVT_MODULE_AFTER_VOTE["stakingModuleAddress"], - SDVT_MODULE_AFTER_VOTE["name"], - SDVT_MODULE_AFTER_VOTE["stakingModuleFee"], - SDVT_MODULE_AFTER_VOTE["targetShare"], - SDVT_MODULE_AFTER_VOTE["treasuryFee"], - SDVT_MODULE_AFTER_VOTE["priorityExitShareThreshold"], - SDVT_MODULE_AFTER_VOTE["maxDepositsPerBlock"], - SDVT_MODULE_AFTER_VOTE["minDepositBlockDistance"], - ), - ], - ) - - validate_repo_upgrade_event(events[6], RepoUpgrade(6, nor_new_app[0])) - validate_app_update_event(events[7], NODE_OPERATORS_REGISTRY_ARAGON_APP_ID, NEW_NODE_OPERATORS_REGISTRY_IMPL) - validate_nor_update(events[8], NOR_VERSION) - - validate_repo_upgrade_event(events[9], RepoUpgrade(2, sdvt_new_app[0])) - validate_app_update_event(events[10], SIMPLE_DVT_ARAGON_APP_ID, NEW_SIMPLE_DVT_IMPL) - validate_nor_update(events[11], SDVT_VERSION) - - # AO - validate_upgrade_events(events[12], NEW_ACCOUNTING_ORACLE_IMPL) - validate_ao_update(events[13], AO_VERSION, AO_CONSENSUS_VERSION) - - validate_grant_role_event(events[14], MANAGE_CONSENSUS_VERSION_ROLE, AGENT, AGENT) - - validate_vebo_consensus_version_set(events[15]) - - validate_revoke_role_event(events[16], MANAGE_CONSENSUS_VERSION_ROLE, AGENT, AGENT) - - validate_evmscript_factory_removed_event(events[17], OLD_TARGET_LIMIT_FACTORY) - - simple_dvt = get_simple_dvt() - - validate_evmscript_factory_added_event( - events[18], - EVMScriptFactoryAdded( - factory_addr=NEW_TARGET_LIMIT_FACTORY, - permissions=( - create_permissions_overloaded(simple_dvt, "updateTargetValidatorsLimits", "uint256,uint256,uint256") - ), - ), - ) - - validate_module_add( - events[19], - StakingModuleItem( - CSM_AFTER_VOTE["id"], - CSM_AFTER_VOTE["stakingModuleAddress"], - CSM_AFTER_VOTE["name"], - CSM_AFTER_VOTE["stakingModuleFee"], - CSM_AFTER_VOTE["targetShare"], - CSM_AFTER_VOTE["treasuryFee"], - CSM_AFTER_VOTE["priorityExitShareThreshold"], - CSM_AFTER_VOTE["maxDepositsPerBlock"], - CSM_AFTER_VOTE["minDepositBlockDistance"], - ), - ) - validate_grant_role_event(events[20], REQUEST_BURN_SHARES_ROLE, CS_ACCOUNTING_ADDRESS, AGENT) - validate_grant_role_event(events[21], RESUME_ROLE, AGENT, AGENT) - - validate_resume_event(events[22]) - validate_revoke_role_event(events[23], RESUME_ROLE, AGENT, AGENT) - validate_updateInitial_epoch(events[24]) - - validate_evmscript_factory_added_event( - events[25], - EVMScriptFactoryAdded( - factory_addr=EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY, - permissions=(create_permissions(csm, "settleELRewardsStealingPenalty")), - ), - ["LogScriptCall", "EVMScriptFactoryAdded", "ScriptResult", "ExecuteVote"], - ) - - validate_hash_consensus_member_removed(events[26], old_oracle_member_to_remove, 5, new_total_members=8) - validate_hash_consensus_member_removed(events[27], old_oracle_member_to_remove, 5, new_total_members=8) - validate_grant_role_event(events[28], MANAGE_MEMBERS_AND_QUORUM_ROLE, AGENT, AGENT) - validate_hash_consensus_member_removed( - events[29], - old_oracle_member_to_remove, - 5, - new_total_members=8, - ) - validate_hash_consensus_member_added(events[30], new_oracle_member_to_add, 5, new_total_members=9) - validate_hash_consensus_member_added( - events[31], - new_oracle_member_to_add, - 5, - new_total_members=9, - ) - validate_hash_consensus_member_added( - events[32], - new_oracle_member_to_add, - 5, - new_total_members=9, - ) - - -def get_staking_router(): - return interface.StakingRouter(STAKING_ROUTER) - - -def get_deposit_security_module_v3(): - return interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE_V3) - - -def get_deposit_security_module_v2(): - return interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE_V2) - - -def get_vebo(): - return interface.ValidatorsExitBusOracle(VALIDATORS_EXIT_BUS_ORACLE) - - -def get_simple_dvt(): - return interface.SimpleDVT(SIMPLE_DVT) - - -def get_nor(): - return interface.NodeOperatorsRegistry(NODE_OPERATORS_REGISTRY) - - -def get_burner(): - return interface.Burner(BURNER) - - -def get_csm(): - return interface.CSModule(CSM_ADDRESS) - - -def get_voting(): - return interface.Voting(VOTING) - - -def get_csm_hash_consensus(): - return interface.CSHashConsensus(CS_ORACLE_HASH_CONSENSUS_ADDRESS) - - -def get_ao(): - return interface.AccountingOracle(ACCOUNTING_ORACLE) - - -def get_easy_track(): - return interface.EasyTrack(EASYTRACK) - - -def get_ao_hash_consensus(): - return interface.HashConsensus(HASH_CONSENSUS_FOR_AO) - - -def get_vebo_hash_consensus(): - return interface.HashConsensus(HASH_CONSENSUS_FOR_VEBO) - - -def check_ossifiable_proxy_impl(proxy, expected_impl): - current_impl_address = proxy.proxy__getImplementation() - assert current_impl_address == expected_impl, f"Expected {expected_impl} impl but got {current_impl_address}" - - -def check_dsm_roles_before_vote(): - staking_router = get_staking_router() - deposit_security_module_v2 = get_deposit_security_module_v2() - deposit_security_module_v3 = get_deposit_security_module_v3() - new_dsm_has_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) - assert not new_dsm_has_unvet_role - - old_dsm_has_pause_role = staking_router.hasRole(STAKING_MODULE_PAUSE_ROLE, deposit_security_module_v2) - - assert old_dsm_has_pause_role - - old_dsm_has_resume_role = staking_router.hasRole(STAKING_MODULE_RESUME_ROLE, deposit_security_module_v2) - - assert old_dsm_has_resume_role - - -def check_dsm_roles_after_vote(): - staking_router = get_staking_router() - deposit_security_module_v2 = get_deposit_security_module_v2() - deposit_security_module_v3 = get_deposit_security_module_v3() - new_dsm_has_unvet_role = staking_router.hasRole(STAKING_MODULE_UNVETTING_ROLE, deposit_security_module_v3) - assert new_dsm_has_unvet_role - - old_dsm_has_pause_role = staking_router.hasRole(STAKING_MODULE_PAUSE_ROLE, deposit_security_module_v2) - assert not old_dsm_has_pause_role - - old_dsm_has_resume_role = staking_router.hasRole(STAKING_MODULE_RESUME_ROLE, deposit_security_module_v2) - assert not old_dsm_has_resume_role - - -def check_vebo_doesnt_have_manage_consensus_role(): - vebo = get_vebo() - agent_has_manage_consensus_role = vebo.hasRole(MANAGE_CONSENSUS_VERSION_ROLE, AGENT) - assert not agent_has_manage_consensus_role - - -def check_module_before_vote(expected_module_data: Dict): - staking_router = Contract.from_abi("StakingContract", STAKING_ROUTER, OLD_SR_ABI) - module = staking_router.getStakingModule(expected_module_data["id"]) - assert module["id"] == expected_module_data["id"] - assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] - assert module["treasuryFee"] == expected_module_data["treasuryFee"] - assert module["stakeShareLimit"] == expected_module_data["targetShare"] - assert "priorityExitShareThreshold" not in module - assert "maxDepositsPerBlock" not in module - assert "minDepositBlockDistance" not in module - - -def check_module_after_vote(expected_module_data: Dict): - staking_router = get_staking_router() - module = staking_router.getStakingModule(expected_module_data["id"]) - assert module["id"] == expected_module_data["id"] - assert module["stakingModuleFee"] == expected_module_data["stakingModuleFee"] - assert module["treasuryFee"] == expected_module_data["treasuryFee"] - assert module["stakeShareLimit"] == expected_module_data["targetShare"] - assert module["priorityExitShareThreshold"] == expected_module_data["priorityExitShareThreshold"] - assert module["maxDepositsPerBlock"] == expected_module_data["maxDepositsPerBlock"] - assert module["minDepositBlockDistance"] == expected_module_data["minDepositBlockDistance"] - - -def assert_repo_before_vote(old_app, version, contract_address, old_content_uri): - assert old_app[0][0] == version - assert old_app[2] == old_content_uri, "Content uri before vote is wrong" - assert old_app[1] == contract_address, "New address should match" - - -def assert_repo_update(new_app, old_app, contract_address, old_content_uri): - assert old_app[1] != new_app[1], "Address should change" - assert new_app[1] == contract_address, "New address should match" - assert new_app[0][0] == old_app[0][0] + 1, "Major version should increment" - assert old_app[2] == new_app[2], "Content uri should not be changed" - assert new_app[2] == old_content_uri, "Content uri should match" - - -# Events check - - -def validate_upgrade_events(events: EventDict, implementation: str): - _events_chain = ["LogScriptCall", "LogScriptCall", "Upgraded", "ScriptResult"] - validate_events_chain([e.name for e in events], _events_chain) - assert events.count("Upgraded") == 1 - assert events["Upgraded"]["implementation"] == implementation, "Wrong proxy implementation address" - - -def validate_dsm_roles_events(events: list[EventDict]): - validate_revoke_role_event( - events[1], - STAKING_MODULE_PAUSE_ROLE, - DEPOSIT_SECURITY_MODULE_V2, - AGENT, - ) - validate_revoke_role_event( - events[2], - STAKING_MODULE_RESUME_ROLE, - DEPOSIT_SECURITY_MODULE_V2, - AGENT, - ) - - validate_grant_role_event( - events[3], - STAKING_MODULE_UNVETTING_ROLE, - DEPOSIT_SECURITY_MODULE_V3, - AGENT, - ) - - -def validate_staking_module_update(event: EventDict, module_items: List[StakingModuleItem]): - assert len(module_items) == 2 - - _events_chain = [ - "LogScriptCall", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "ContractVersionSet", - ] - - validate_events_chain([e.name for e in event], _events_chain) - - assert event.count("StakingModuleFeesSet") == 2 - assert event.count("StakingModuleShareLimitSet") == 2 - assert event.count("StakingModuleMinDepositBlockDistanceSet") == 2 - assert event.count("StakingModuleMaxDepositsPerBlockSet") == 2 - assert event.count("ContractVersionSet") == 1 - - # curated - assert event["StakingModuleShareLimitSet"][0]["stakingModuleId"] == module_items[0].id - assert event["StakingModuleShareLimitSet"][0]["stakeShareLimit"] == module_items[0].stake_share_limit - assert ( - event["StakingModuleShareLimitSet"][0]["priorityExitShareThreshold"] - == module_items[0].priority_exit_share_threshold - ) - assert event["StakingModuleFeesSet"][0]["stakingModuleId"] == module_items[0].id - assert event["StakingModuleFeesSet"][0]["stakingModuleFee"] == module_items[0].staking_module_fee - assert event["StakingModuleFeesSet"][0]["treasuryFee"] == module_items[0].treasury_fee - - assert ( - event["StakingModuleMaxDepositsPerBlockSet"][0]["maxDepositsPerBlock"] == module_items[0].max_deposits_per_block - ) - - assert ( - event["StakingModuleMinDepositBlockDistanceSet"][0]["minDepositBlockDistance"] - == module_items[0].min_deposit_block_distance - ) - - assert event["ContractVersionSet"]["version"] == SR_VERSION - - assert event["StakingModuleShareLimitSet"][1]["stakingModuleId"] == module_items[1].id - assert event["StakingModuleShareLimitSet"][1]["stakeShareLimit"] == module_items[1].stake_share_limit - assert ( - event["StakingModuleShareLimitSet"][1]["priorityExitShareThreshold"] - == module_items[1].priority_exit_share_threshold - ) - assert event["StakingModuleFeesSet"][1]["stakingModuleId"] == module_items[1].id - assert event["StakingModuleFeesSet"][1]["stakingModuleFee"] == module_items[1].staking_module_fee - assert event["StakingModuleFeesSet"][1]["treasuryFee"] == module_items[1].treasury_fee - - assert ( - event["StakingModuleMaxDepositsPerBlockSet"][1]["maxDepositsPerBlock"] == module_items[1].max_deposits_per_block - ) - - assert ( - event["StakingModuleMinDepositBlockDistanceSet"][1]["minDepositBlockDistance"] - == module_items[1].min_deposit_block_distance - ) - - -def validate_nor_update(event: EventDict, version): - _events_chain = [ - "LogScriptCall", - "ContractVersionSet", - "RewardDistributionStateChanged", - ] - validate_events_chain([e.name for e in event], _events_chain) - - assert event["ContractVersionSet"]["version"] == version - assert event["RewardDistributionStateChanged"]["state"] == DISTRIBUTED - - -def validate_ao_update(event: EventDict, version, ao_consensus_version): - _events_chain = [ - "LogScriptCall", - "ContractVersionSet", - "ConsensusVersionSet", - ] - validate_events_chain([e.name for e in event], _events_chain) - - assert event["ContractVersionSet"]["version"] == version - assert event["ConsensusVersionSet"]["version"] == ao_consensus_version - assert event["ConsensusVersionSet"]["prevVersion"] == ao_consensus_version - 1 - - -def validate_vebo_consensus_version_set(event: EventDict): - _events_chain = ["LogScriptCall", "LogScriptCall", "ConsensusVersionSet", "ScriptResult"] - validate_events_chain([e.name for e in event], _events_chain) - assert event["ConsensusVersionSet"]["version"] == VEBO_CONSENSUS_VERSION - - -def validate_resume_event(event: EventDict): - _events_chain = ["LogScriptCall", "LogScriptCall", "Resumed", "ScriptResult"] - validate_events_chain([e.name for e in event], _events_chain) - assert event.count("Resumed") == 1 - - -def validate_updateInitial_epoch(event: EventDict): - _events_chain = ["LogScriptCall", "LogScriptCall", "FrameConfigSet", "ScriptResult"] - validate_events_chain([e.name for e in event], _events_chain) - assert event["FrameConfigSet"]["newInitialEpoch"] == CS_ORACLE_INITIAL_EPOCH - - -def validate_module_add(event, csm: StakingModuleItem): - _events_chain = [ - "LogScriptCall", - "LogScriptCall", - "StakingRouterETHDeposited", - "StakingModuleAdded", - "StakingModuleShareLimitSet", - "StakingModuleFeesSet", - "StakingModuleMaxDepositsPerBlockSet", - "StakingModuleMinDepositBlockDistanceSet", - "ScriptResult", - ] - validate_events_chain([e.name for e in event], _events_chain) - - assert event["StakingRouterETHDeposited"]["stakingModuleId"] == csm.id - assert event["StakingRouterETHDeposited"]["amount"] == 0 - assert event["StakingModuleAdded"]["stakingModuleId"] == csm.id - assert event["StakingModuleAdded"]["stakingModule"] == csm.staking_module_address - assert event["StakingModuleAdded"]["name"] == csm.name - - assert event["StakingModuleShareLimitSet"]["stakingModuleId"] == csm.id - assert event["StakingModuleShareLimitSet"]["stakeShareLimit"] == csm.stake_share_limit - assert event["StakingModuleShareLimitSet"]["priorityExitShareThreshold"] == csm.priority_exit_share_threshold - - assert event["StakingModuleFeesSet"]["stakingModuleId"] == csm.id - assert event["StakingModuleFeesSet"]["stakingModuleFee"] == csm.staking_module_fee - assert event["StakingModuleFeesSet"]["treasuryFee"] == csm.treasury_fee - - assert event["StakingModuleMaxDepositsPerBlockSet"]["maxDepositsPerBlock"] == csm.max_deposits_per_block - - assert event["StakingModuleMinDepositBlockDistanceSet"]["minDepositBlockDistance"] == csm.min_deposit_block_distance - - -def check_csm(): - staking_router = get_staking_router() - cs = staking_router.getStakingModule(3) - - assert cs["name"] == CSM_AFTER_VOTE["name"] - assert cs["stakingModuleFee"] == CSM_AFTER_VOTE["stakingModuleFee"] - assert cs["treasuryFee"] == CSM_AFTER_VOTE["treasuryFee"] - assert cs["stakeShareLimit"] == CSM_AFTER_VOTE["targetShare"] - assert cs["priorityExitShareThreshold"] == CSM_AFTER_VOTE["priorityExitShareThreshold"] - assert cs["maxDepositsPerBlock"] == CSM_AFTER_VOTE["maxDepositsPerBlock"] - assert cs["minDepositBlockDistance"] == CSM_AFTER_VOTE["minDepositBlockDistance"] From df2058668c6c3cbb4831afd98344c01d1361b6f3 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Tue, 29 Oct 2024 19:37:30 +0500 Subject: [PATCH 208/220] upload csm keys with batches fix rewards calculation with csm alive --- tests/regression/test_pause_resume.py | 14 ++++++++++++-- utils/test/csm_helpers.py | 24 +++++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/tests/regression/test_pause_resume.py b/tests/regression/test_pause_resume.py index 465a991dc..9d9489554 100644 --- a/tests/regression/test_pause_resume.py +++ b/tests/regression/test_pause_resume.py @@ -278,12 +278,14 @@ def test_paused_staking_module_can_reward(burner: Contract, stranger): print(report_tx.events["Transfer"]) module_index = 0 simple_dvt_index = 1 + csm_index = 2 if report_tx.events["Transfer"][module_index]["to"] == burner.address: module_index += 1 simple_dvt_index += 1 + csm_index += 1 - agent_index = module_index + 2 + agent_index = module_index + 3 assert report_tx.events["Transfer"][module_index]["to"] == module_address assert report_tx.events["Transfer"][module_index]["from"] == ZERO_ADDRESS assert report_tx.events["Transfer"][agent_index]["to"] == contracts.agent @@ -299,8 +301,16 @@ def test_paused_staking_module_can_reward(burner: Contract, stranger): * simple_dvt_stats["treasuryFee"] // 100_00 ) + csm_stats = contracts.staking_router.getStakingModule(3) + csm_treasury_fee = ( + report_tx.events["Transfer"][csm_index]["value"] + * 100_00 + // csm_stats["stakingModuleFee"] + * csm_stats["treasuryFee"] + // 100_00 + ) assert almostEqWithDiff( - report_tx.events["Transfer"][module_index]["value"] + simple_dvt_treasury_fee, + report_tx.events["Transfer"][module_index]["value"] + simple_dvt_treasury_fee + csm_treasury_fee, report_tx.events["Transfer"][agent_index]["value"], 100, ) diff --git a/utils/test/csm_helpers.py b/utils/test/csm_helpers.py index 2897061ec..4435680d7 100644 --- a/utils/test/csm_helpers.py +++ b/utils/test/csm_helpers.py @@ -130,6 +130,7 @@ def get_ea_members(): "0xf99292f2fccc3f4fa8cef73512bd5f21a46214d922dfed8e8a65f763c13dfb72"]) ) + def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5, curve_id=0): pubkeys_batch = random_pubkeys_batch(keys_count) signatures_batch = random_signatures_batch(keys_count) @@ -149,14 +150,23 @@ def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5, c return csm.getNodeOperatorsCount() - 1 + def csm_upload_keys(csm, accounting, no_id, keys_count=5): manager_address = csm.getNodeOperator(no_id)["managerAddress"] - pubkeys_batch = random_pubkeys_batch(keys_count) - signatures_batch = random_signatures_batch(keys_count) - csm.addValidatorKeysETH(no_id, keys_count, pubkeys_batch, signatures_batch, - {"from": manager_address, - "value": accounting.getRequiredBondForNextKeys(no_id, keys_count)} - ) + set_balance_in_wei(manager_address, accounting.getRequiredBondForNextKeys(no_id, keys_count) + ETH(1)) + + keys_batch = 100 + remaining_keys = keys_count + while remaining_keys > 0: + keys_batch = min(keys_batch, remaining_keys) + pubkeys_batch = random_pubkeys_batch(keys_batch) + signatures_batch = random_signatures_batch(keys_batch) + value = accounting.getRequiredBondForNextKeys(no_id, keys_count) + csm.addValidatorKeysETH(no_id, keys_batch, pubkeys_batch, signatures_batch, { + "from": csm.getNodeOperator(no_id)["managerAddress"], + "value": value + }) + remaining_keys -= keys_batch def fill_csm_operators_with_keys(target_operators_count, keys_count): @@ -166,7 +176,7 @@ def fill_csm_operators_with_keys(target_operators_count, keys_count): csm_node_operators_before = contracts.csm.getNodeOperatorsCount() added_operators_count = 0 - for no_id in range(0, csm_node_operators_before): + for no_id in range(0, min(csm_node_operators_before, target_operators_count)): depositable_keys = contracts.csm.getNodeOperator(no_id)["depositableValidatorsCount"] if depositable_keys < keys_count: csm_upload_keys(contracts.csm, contracts.cs_accounting, no_id, keys_count - depositable_keys) From b8b8470cfa141e502c3721639d52a54b5141593d Mon Sep 17 00:00:00 2001 From: skhomuti Date: Wed, 30 Oct 2024 11:01:49 +0500 Subject: [PATCH 209/220] fix happy path test, add expected csm transfer event --- tests/regression/test_all_round_happy_path.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/regression/test_all_round_happy_path.py b/tests/regression/test_all_round_happy_path.py index 4ee85c7ae..16ca7f80f 100644 --- a/tests/regression/test_all_round_happy_path.py +++ b/tests/regression/test_all_round_happy_path.py @@ -138,6 +138,7 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): treasury = contracts.lido_locator.treasury() nor = contracts.node_operators_registry.address sdvt = contracts.simple_dvt.address + csm = contracts.csm.address nor_operators_count = contracts.node_operators_registry.getNodeOperatorsCount() sdvt_operators_count = contracts.simple_dvt.getNodeOperatorsCount() @@ -227,12 +228,16 @@ def test_all_round_happy_path(accounts, stranger, steth_holder, eth_whale): assert transfer_event[2]["from"] == ZERO_ADDRESS assert transfer_event[2]["to"] == sdvt + # csm assert transfer_event[3]["from"] == ZERO_ADDRESS - assert transfer_event[3]["to"] == treasury + assert transfer_event[3]["to"] == csm + + assert transfer_event[4]["from"] == ZERO_ADDRESS + assert transfer_event[4]["to"] == treasury assert almostEqEth( treasury_balance_after_rebase, - treasury_balance_before_rebase + contracts.lido.getSharesByPooledEth(transfer_event[3]["value"]), + treasury_balance_before_rebase + contracts.lido.getSharesByPooledEth(transfer_event[4]["value"]), ) assert treasury_balance_after_rebase > treasury_balance_before_rebase From 8bb06ae5c21c36b913e65492b201d3443c11d5c5 Mon Sep 17 00:00:00 2001 From: skhomuti Date: Tue, 12 Nov 2024 16:27:49 +0700 Subject: [PATCH 210/220] fix unstable shares check in csm claim --- tests/regression/test_csm.py | 34 ++++++++++++++++++---------------- utils/test/csm_helpers.py | 2 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tests/regression/test_csm.py b/tests/regression/test_csm.py index dd6fa7d11..6b5ffe6f2 100644 --- a/tests/regression/test_csm.py +++ b/tests/regression/test_csm.py @@ -74,14 +74,13 @@ def ref_slot(): return ref_slot -@pytest.fixture -def distribute_reward_tree(deposits_to_csm, fee_oracle, fee_distributor, node_operator, ref_slot): - consensus_version = fee_oracle.getConsensusVersion() - oracle_version = fee_oracle.getContractVersion() +def distribute_reward_tree(node_operator, ref_slot): + consensus_version = contracts.cs_fee_oracle.getConsensusVersion() + oracle_version = contracts.cs_fee_oracle.getContractVersion() rewards = ETH(0.05) oracle_report(cl_diff=rewards) - distributed_shares = contracts.lido.sharesOf(fee_distributor) + distributed_shares = contracts.lido.sharesOf(contracts.cs_fee_distributor) assert distributed_shares > 0 report, report_hash, tree = prepare_csm_report({node_operator: distributed_shares}, ref_slot) @@ -93,7 +92,7 @@ def distribute_reward_tree(deposits_to_csm, fee_oracle, fee_distributor, node_op contracts.csm_hash_consensus, ) - fee_oracle.submitReportData(report, oracle_version, {"from": submitter}) + contracts.cs_fee_oracle.submitReportData(report, oracle_version, {"from": submitter}) return tree @@ -316,20 +315,23 @@ def test_csm_wsteth_bond(csm, accounting, node_operator): @pytest.mark.usefixtures("deposits_to_csm") -def test_csm_claim_rewards_steth(csm, distribute_reward_tree, node_operator, fee_distributor): - tree = distribute_reward_tree.tree - shares = tree.values[0]["value"][1] - proof = list(tree.get_proof(tree.find(tree.leaf((node_operator, shares))))) +def test_csm_claim_rewards_steth(csm, node_operator, ref_slot): reward_address = csm.getNodeOperator(node_operator)["rewardAddress"] shares_before = contracts.lido.sharesOf(reward_address) + accounting_shares_before = contracts.lido.sharesOf(contracts.cs_accounting) + + tree = distribute_reward_tree(node_operator, ref_slot).tree + shares = tree.values[0]["value"][1] + proof = list(tree.get_proof(tree.find(tree.leaf((node_operator, shares))))) csm.claimRewardsStETH(node_operator, ETH(1), shares, proof, {"from": reward_address}) - # subtract 10 to avoid rounding errors - assert contracts.lido.sharesOf(reward_address) > shares_before + shares - 10 + shares_after = contracts.lido.sharesOf(reward_address) + accounting_shares_after = contracts.lido.sharesOf(contracts.cs_accounting) + assert shares_after == shares_before + (accounting_shares_before + shares - accounting_shares_after) @pytest.mark.usefixtures("deposits_to_csm") -def test_csm_claim_rewards_wsteth(csm, distribute_reward_tree, node_operator, fee_distributor): - tree = distribute_reward_tree.tree +def test_csm_claim_rewards_wsteth(csm, node_operator, ref_slot): + tree = distribute_reward_tree(node_operator, ref_slot).tree shares = tree.values[0]["value"][1] proof = list(tree.get_proof(tree.find(tree.leaf((node_operator, shares))))) reward_address = csm.getNodeOperator(node_operator)["rewardAddress"] @@ -339,8 +341,8 @@ def test_csm_claim_rewards_wsteth(csm, distribute_reward_tree, node_operator, fe assert contracts.wsteth.balanceOf(reward_address) > wsteth_before @pytest.mark.usefixtures("deposits_to_csm") -def test_csm_claim_rewards_eth(csm, distribute_reward_tree, node_operator, fee_distributor): - tree = distribute_reward_tree.tree +def test_csm_claim_rewards_eth(csm, node_operator, ref_slot): + tree = distribute_reward_tree(node_operator, ref_slot).tree shares = tree.values[0]["value"][1] proof = list(tree.get_proof(tree.find(tree.leaf((node_operator, shares))))) reward_address = csm.getNodeOperator(node_operator)["rewardAddress"] diff --git a/utils/test/csm_helpers.py b/utils/test/csm_helpers.py index 4435680d7..eb374780c 100644 --- a/utils/test/csm_helpers.py +++ b/utils/test/csm_helpers.py @@ -136,7 +136,7 @@ def csm_add_node_operator(csm, accounting, node_operator, proof, keys_count=5, c signatures_batch = random_signatures_batch(keys_count) value = accounting.getBondAmountByKeysCount['uint256,uint256'](keys_count, curve_id) - set_balance_in_wei(node_operator, value + ETH(1)) + set_balance_in_wei(node_operator, value + ETH(10)) csm.addNodeOperatorETH( keys_count, From d587fc756b3e1709e61b1d364b4c83b9b9c32053 Mon Sep 17 00:00:00 2001 From: Nikita P Date: Tue, 12 Nov 2024 18:39:24 +0000 Subject: [PATCH 211/220] fix: not enough eth to make transaction --- tests/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 922e22635..111798ad7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -29,7 +29,7 @@ def shared_setup(fn_isolation): @pytest.fixture(scope="session", autouse=True) def network_gas_price(): - network.gas_price("2 gwei") + network.gas_price("99999999 gwei") @pytest.fixture(scope="function") def deployer(): @@ -260,7 +260,7 @@ def add_balance_check_middleware(): # TODO: Such implicit manipulation of the balances may lead to hard-debugging errors in the future. # Better to return back balance after request is done. def ensure_balance(address): - if web3.eth.get_balance(address) < ETH(1): + if web3.eth.get_balance(address) < ETH(1000000): set_balance(address, 1000000) def balance_check_middleware(make_request, web3): From 63cc9fe67bd6d6c37b8b1a6fb60ca5bfa04457cc Mon Sep 17 00:00:00 2001 From: Nikita P Date: Tue, 12 Nov 2024 18:40:42 +0000 Subject: [PATCH 212/220] fix: revert gas price --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 111798ad7..5e017bee2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -29,7 +29,7 @@ def shared_setup(fn_isolation): @pytest.fixture(scope="session", autouse=True) def network_gas_price(): - network.gas_price("99999999 gwei") + network.gas_price("2 gwei") @pytest.fixture(scope="function") def deployer(): From b895c8d7daa20b4646645dec885e0c2323e2614d Mon Sep 17 00:00:00 2001 From: Nikita P Date: Tue, 12 Nov 2024 21:50:56 +0000 Subject: [PATCH 213/220] fix: eth check --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 5e017bee2..b4ca025e7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -260,7 +260,7 @@ def add_balance_check_middleware(): # TODO: Such implicit manipulation of the balances may lead to hard-debugging errors in the future. # Better to return back balance after request is done. def ensure_balance(address): - if web3.eth.get_balance(address) < ETH(1000000): + if web3.eth.get_balance(address) < ETH(10): set_balance(address, 1000000) def balance_check_middleware(make_request, web3): From de875a702d2599cfb2ff9ad73a12a731097afecd Mon Sep 17 00:00:00 2001 From: Nikita P Date: Wed, 13 Nov 2024 18:47:55 +0000 Subject: [PATCH 214/220] fix: ensure balance (ii) --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index b4ca025e7..ea7b00271 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -260,7 +260,7 @@ def add_balance_check_middleware(): # TODO: Such implicit manipulation of the balances may lead to hard-debugging errors in the future. # Better to return back balance after request is done. def ensure_balance(address): - if web3.eth.get_balance(address) < ETH(10): + if web3.eth.get_balance(address) < ETH(999): set_balance(address, 1000000) def balance_check_middleware(make_request, web3): From 678e83cdfe20ddf6d1b87536de161cb141606e0a Mon Sep 17 00:00:00 2001 From: Eugene M Date: Thu, 14 Nov 2024 23:16:47 +0300 Subject: [PATCH 215/220] fix: remove balance_check middleware side effects --- tests/conftest.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index ea7b00271..195e99bcf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,7 +15,7 @@ from utils.config import * from utils.txs.deploy import deploy_from_prepared_tx from utils.test.helpers import ETH -from utils.balance import set_balance +from utils.balance import set_balance, set_balance_in_wei from functools import wraps ENV_OMNIBUS_BYPASS_EVENTS_DECODING = "OMNIBUS_BYPASS_EVENTS_DECODING" @@ -27,10 +27,12 @@ def shared_setup(fn_isolation): pass + @pytest.fixture(scope="session", autouse=True) def network_gas_price(): network.gas_price("2 gwei") + @pytest.fixture(scope="function") def deployer(): return accounts[0] @@ -63,10 +65,12 @@ def delegate1(): def delegate2(): return set_balance("0x100b896F2Dd8c4Ca619db86BCDDb7E085143C1C5", 100000) + @pytest.fixture(scope="module") def trp_recipient(accounts): return set_balance("0x228cCaFeA1fa21B74257Af975A9D84d87188c61B", 100000) + @pytest.fixture(scope="module") def eth_whale(accounts): if network_name() in ("goerli", "goerli-fork"): @@ -253,24 +257,36 @@ def parse_events_from_local_abi(): # Added contract will resolve from address during state._find_contract without a request to Etherscan state._add_contract(contract) + @pytest.fixture(scope="session", autouse=True) def add_balance_check_middleware(): - web3.middleware_onion.add(balance_check_middleware, name='balance_check') + web3.middleware_onion.add(balance_check_middleware, name="balance_check") + # TODO: Such implicit manipulation of the balances may lead to hard-debugging errors in the future. -# Better to return back balance after request is done. -def ensure_balance(address): - if web3.eth.get_balance(address) < ETH(999): - set_balance(address, 1000000) +def ensure_balance(address) -> int: + old_balance = web3.eth.get_balance(address) + if old_balance < ETH(999): + set_balance_in_wei(address, ETH(1000000)) + return web3.eth.get_balance(address) - old_balance + def balance_check_middleware(make_request, web3): @wraps(make_request) def middleware(method, params): + from_address = None + balance_diff = 0 if method in ["eth_sendTransaction", "eth_sendRawTransaction"]: transaction = params[0] - from_address = transaction.get('from') + from_address = transaction.get("from") if from_address: - ensure_balance(from_address) + balance_diff = ensure_balance(from_address) + + result = make_request(method, params) + if balance_diff > 0: + new_balance = max(0, web3.eth.get_balance(from_address) - balance_diff) + set_balance_in_wei(from_address, new_balance) + + return result - return make_request(method, params) return middleware From b9dec0b4dc3ee436bf93f3c7d3f5ac3df5d16f26 Mon Sep 17 00:00:00 2001 From: Eugene M Date: Fri, 15 Nov 2024 00:47:07 +0300 Subject: [PATCH 216/220] fix: add finally block --- tests/conftest.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 195e99bcf..da9b0c576 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -275,17 +275,21 @@ def balance_check_middleware(make_request, web3): @wraps(make_request) def middleware(method, params): from_address = None + result = None balance_diff = 0 + if method in ["eth_sendTransaction", "eth_sendRawTransaction"]: transaction = params[0] from_address = transaction.get("from") if from_address: balance_diff = ensure_balance(from_address) - result = make_request(method, params) - if balance_diff > 0: - new_balance = max(0, web3.eth.get_balance(from_address) - balance_diff) - set_balance_in_wei(from_address, new_balance) + try: + result = make_request(method, params) + finally: + if balance_diff > 0: + new_balance = max(0, web3.eth.get_balance(from_address) - balance_diff) + set_balance_in_wei(from_address, new_balance) return result From 50383fc22befc31f6ecc7d9e8eebd4fa3ea3b204 Mon Sep 17 00:00:00 2001 From: Eugene M Date: Fri, 15 Nov 2024 20:16:43 +0300 Subject: [PATCH 217/220] chore: print out balance when can't set it up --- utils/balance.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/balance.py b/utils/balance.py index 570d96756..2ed745c26 100644 --- a/utils/balance.py +++ b/utils/balance.py @@ -1,6 +1,7 @@ from brownie import accounts, web3 from utils.test.helpers import ETH + def set_balance_in_wei(address, balance): account = accounts.at(address, force=True) providers = ["evm_setAccountBalance", "hardhat_setBalance", "anvil_setBalance"] @@ -15,9 +16,10 @@ def set_balance_in_wei(address, balance): if e.args[0].get("message") != f"Method {provider} is not supported": raise e - assert account.balance() == balance, f"Failed to set balance for account: {address}" + assert account.balance() == balance, f"Failed to set balance {balance} for account: {address}" return account + def set_balance(address, balanceInEth): balance = ETH(balanceInEth) From 89b19f86d6174f081fc21479fab63b3704164be6 Mon Sep 17 00:00:00 2001 From: Eugene M Date: Fri, 15 Nov 2024 20:18:01 +0300 Subject: [PATCH 218/220] fix: sync the oracle simulation code + override --- utils/test/oracle_report_helpers.py | 59 ++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/utils/test/oracle_report_helpers.py b/utils/test/oracle_report_helpers.py index 8189c8296..0b008defc 100644 --- a/utils/test/oracle_report_helpers.py +++ b/utils/test/oracle_report_helpers.py @@ -8,7 +8,7 @@ from eth_abi.abi import encode from hexbytes import HexBytes -from utils.config import (contracts, AO_CONSENSUS_VERSION) +from utils.config import contracts, AO_CONSENSUS_VERSION from utils.test.exit_bus_data import encode_data from utils.test.helpers import ETH, GWEI, eth_balance from utils.test.merkle_tree import Tree @@ -16,7 +16,7 @@ ZERO_HASH = bytes([0] * 32) ZERO_BYTES32 = HexBytes(ZERO_HASH) ONE_DAY = 1 * 24 * 60 * 60 -SHARE_RATE_PRECISION = 10 ** 27 +SHARE_RATE_PRECISION = 10**27 EXTRA_DATA_FORMAT_EMPTY = 0 EXTRA_DATA_FORMAT_LIST = 1 @@ -113,7 +113,7 @@ def prepare_csm_report(node_operators_rewards: dict, ref_slot): shares = node_operators_rewards.copy() if len(shares) < 2: # put a stone - shares[2 ** 64 - 1] = 0 + shares[2**64 - 1] = 0 tree = Tree.new(tuple((no_id, amount) for (no_id, amount) in shares.items())) # semi-random values @@ -143,8 +143,20 @@ def encode_data_from_abi(data, abi, func_name): def get_finalization_batches( share_rate: int, limited_withdrawal_vault_balance, limited_el_rewards_vault_balance ) -> list[int]: - (_, _, _, _, _, _, _, requestTimestampMargin, _, _, _, - _) = contracts.oracle_report_sanity_checker.getOracleReportLimits() + ( + _, + _, + _, + _, + _, + _, + _, + requestTimestampMargin, + _, + _, + _, + _, + ) = contracts.oracle_report_sanity_checker.getOracleReportLimits() buffered_ether = contracts.lido.getBufferedEther() unfinalized_steth = contracts.withdrawal_queue.unfinalizedStETH() reserved_buffer = min(buffered_ether, unfinalized_steth) @@ -219,7 +231,7 @@ def push_oracle_report( extraDataItemsCount=extraDataItemsCount, ) submitter = reach_consensus(refSlot, hash, consensusVersion, contracts.hash_consensus_for_accounting_oracle, silent) - accounts[0].transfer(submitter, 10 ** 19) + accounts[0].transfer(submitter, 10**19) # print(contracts.oracle_report_sanity_checker.getOracleReportLimits()) report_tx = contracts.accounting_oracle.submitReportData(items, oracleVersion, {"from": submitter}) if not silent: @@ -230,8 +242,9 @@ def push_oracle_report( if not silent: print("Submitted empty extra data report") else: - extra_report_tx_list = [contracts.accounting_oracle.submitReportExtraDataList(data, {"from": submitter}) for - data in extraDataList] + extra_report_tx_list = [ + contracts.accounting_oracle.submitReportExtraDataList(data, {"from": submitter}) for data in extraDataList + ] if not silent: print("Submitted NOT empty extra data report") @@ -263,6 +276,22 @@ def simulate_report( ): (_, SECONDS_PER_SLOT, GENESIS_TIME) = contracts.hash_consensus_for_accounting_oracle.getChainConfig() reportTime = GENESIS_TIME + refSlot * SECONDS_PER_SLOT + + override_slot = web3.keccak(text="lido.BaseOracle.lastProcessingRefSlot").hex() + state_override = { + contracts.accounting_oracle.address: { + # Fix: Sanity checker uses `lastProcessingRefSlot` from AccountingOracle to + # properly process negative rebase sanity checks. Since current simulation skips call to AO, + # setting up `lastProcessingRefSlot` directly. + # + # The code is taken from the current production `lido-oracle` implementation + # source: https://github.com/lidofinance/lido-oracle/blob/da393bf06250344a4d06dce6d1ac6a3ddcb9c7a3/src/providers/execution/contracts/lido.py#L93-L95 + "stateDiff": { + override_slot: refSlot, + }, + }, + } + try: return contracts.lido.handleOracleReport.call( reportTime, @@ -276,9 +305,19 @@ def simulate_report( 0, {"from": contracts.accounting_oracle.address}, block_identifier=block_identifier, + override=state_override, ) except VirtualMachineError: # workaround for empty revert message from ganache on eth_call + + # override storage value of the processing reference slot to make the simulation sound + # Since it's not possible to pass an override as a part of the state-changing transaction + web3.provider.make_request( + # can assume ganache only here + "evm_setAccountStorageAt", + [contracts.accounting_oracle.address, override_slot, refSlot], + ) + contracts.lido.handleOracleReport( reportTime, ONE_DAY, @@ -301,7 +340,9 @@ def wait_to_next_available_report_time(consensus_contract): except VirtualMachineError as e: if "InitialEpochIsYetToArrive" in str(e): frame_config = consensus_contract.getFrameConfig() - chain.sleep(GENESIS_TIME + 1 + (frame_config["initialEpoch"] * SLOTS_PER_EPOCH * SECONDS_PER_SLOT) - chain.time()) + chain.sleep( + GENESIS_TIME + 1 + (frame_config["initialEpoch"] * SLOTS_PER_EPOCH * SECONDS_PER_SLOT) - chain.time() + ) chain.mine(1) (refSlot, _) = consensus_contract.getCurrentFrame() else: From 7c2b44ca287f8341e26c0552e55eda1a839faf38 Mon Sep 17 00:00:00 2001 From: Eugene M Date: Fri, 15 Nov 2024 20:23:14 +0300 Subject: [PATCH 219/220] fix: update the negative rebase test --- .../test_neg_rebase_sanity_checks.py | 50 +++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/tests/regression/test_neg_rebase_sanity_checks.py b/tests/regression/test_neg_rebase_sanity_checks.py index 6e0d86799..6c62ec07c 100644 --- a/tests/regression/test_neg_rebase_sanity_checks.py +++ b/tests/regression/test_neg_rebase_sanity_checks.py @@ -16,6 +16,7 @@ INACTIVITY_PENALTIES_AMOUNT_PWEI = 101 ONE_PWEI = ETH(0.001) + @pytest.fixture(scope="module") def oracle_report_sanity_checker() -> Contract: return contracts.oracle_report_sanity_checker @@ -28,8 +29,11 @@ def test_negative_rebase_correct_exited_validators_count_pos_rebase(oracle_repor reported_validators = exited_validators_count() reported_validators_values = [value + 2 for value in reported_validators.values()] - oracle_report(cl_diff=ETH(300), stakingModuleIdsWithNewlyExitedValidators=list(reported_validators.keys()), - numExitedValidatorsByStakingModule=reported_validators_values) + oracle_report( + cl_diff=ETH(300), + stakingModuleIdsWithNewlyExitedValidators=list(reported_validators.keys()), + numExitedValidatorsByStakingModule=reported_validators_values, + ) count = oracle_report_sanity_checker.getReportDataCount() assert count > 0 @@ -37,6 +41,7 @@ def test_negative_rebase_correct_exited_validators_count_pos_rebase(oracle_repor assert stored_exited_validators == sum(reported_validators_values) + def test_negative_rebase_correct_exited_validators_count_neg_rebase(oracle_report_sanity_checker): locator = contracts.lido_locator assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() @@ -44,8 +49,11 @@ def test_negative_rebase_correct_exited_validators_count_neg_rebase(oracle_repor reported_validators = exited_validators_count() reported_validators_values = [value + 3 for value in reported_validators.values()] - oracle_report(cl_diff=-ETH(40000), stakingModuleIdsWithNewlyExitedValidators=list(reported_validators.keys()), - numExitedValidatorsByStakingModule=reported_validators_values) + oracle_report( + cl_diff=-ETH(40000), + stakingModuleIdsWithNewlyExitedValidators=list(reported_validators.keys()), + numExitedValidatorsByStakingModule=reported_validators_values, + ) count = oracle_report_sanity_checker.getReportDataCount() assert count > 0 @@ -53,6 +61,7 @@ def test_negative_rebase_correct_exited_validators_count_neg_rebase(oracle_repor assert stored_exited_validators == sum(reported_validators_values) + def test_negative_rebase_correct_balance_neg_rebase(oracle_report_sanity_checker): locator = contracts.lido_locator assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() @@ -78,12 +87,32 @@ def test_blocked_huge_negative_rebase(oracle_report_sanity_checker): locator = contracts.lido_locator assert oracle_report_sanity_checker.address == locator.oracleReportSanityChecker() + # Advance the chain 60 days more without accounting oracle reports + # The idea is to simplify the calculation of the exited validators for 18 and 54 days ago + chain.sleep(60 * 24 * 60 * 60) + chain.mine(1) + (_, cl_validators, cl_balance) = contracts.lido.getBeaconStat() + count = oracle_report_sanity_checker.getReportDataCount() + assert count > 0 + (_, stored_exited_validators, _) = oracle_report_sanity_checker.reportData(count - 1) - max_cl_balance = (INITIAL_SLASHING_AMOUNT_PWEI + INACTIVITY_PENALTIES_AMOUNT_PWEI) * ONE_PWEI * cl_validators - error_cl_decrease = cl_balance // 10 # 10% of current balance will lead to error + max_cl_balance = ( + (INITIAL_SLASHING_AMOUNT_PWEI + INACTIVITY_PENALTIES_AMOUNT_PWEI) + * ONE_PWEI + * (cl_validators - stored_exited_validators) + ) + error_cl_decrease = cl_balance // 10 # 10% of current balance will lead to error + + print(encode_error("IncorrectCLBalanceDecrease(uint256, uint256)", [error_cl_decrease, max_cl_balance])) with reverts(encode_error("IncorrectCLBalanceDecrease(uint256, uint256)", [error_cl_decrease, max_cl_balance])): - oracle_report(cl_diff=-error_cl_decrease, exclude_vaults_balances=True, silent=True) + oracle_report( + cl_diff=-error_cl_decrease, + exclude_vaults_balances=True, + simulation_block_identifier=chain.height, + silent=True, + ) + def test_negative_rebase_more_than_54_reports(oracle_report_sanity_checker): locator = contracts.lido_locator @@ -92,8 +121,11 @@ def test_negative_rebase_more_than_54_reports(oracle_report_sanity_checker): reported_validators_values = exited_validators_count().values() for _ in range(58): reported_validators_values = [value + 3 for value in reported_validators_values] - oracle_report(cl_diff=-ETH(400), stakingModuleIdsWithNewlyExitedValidators=exited_validators_count().keys(), - numExitedValidatorsByStakingModule=reported_validators_values) + oracle_report( + cl_diff=-ETH(400), + stakingModuleIdsWithNewlyExitedValidators=exited_validators_count().keys(), + numExitedValidatorsByStakingModule=reported_validators_values, + ) count = oracle_report_sanity_checker.getReportDataCount() assert count > 0 From 1d111dbf0bec46a059ed72d6e4f93aa60c75e0b9 Mon Sep 17 00:00:00 2001 From: Eugene M Date: Fri, 15 Nov 2024 21:22:07 +0300 Subject: [PATCH 220/220] fix: set initial balance for stranger --- tests/regression/test_staking_limits.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/regression/test_staking_limits.py b/tests/regression/test_staking_limits.py index 67c4651ba..8a48ac8bd 100644 --- a/tests/regression/test_staking_limits.py +++ b/tests/regression/test_staking_limits.py @@ -1,12 +1,14 @@ """ Tests for lido staking limits """ + import pytest import eth_abi from brownie import web3, convert, reverts, ZERO_ADDRESS, chain from utils.config import contracts from utils.test.helpers import ONE_ETH +from utils.balance import set_balance @pytest.fixture(scope="module") @@ -88,6 +90,8 @@ def test_staking_limit_initial_not_zero(): [(10**6, 10**4), (10**12, 10**10), (10**18, 10**16)], ) def test_staking_limit_updates_per_block_correctly(voting, stranger, limit_max, limit_per_block): + set_balance(stranger.address, 1000000) + # Should update staking limits after submit contracts.lido.setStakingLimit(limit_max, limit_per_block, {"from": voting}) staking_limit_before = contracts.lido.getCurrentStakeLimit()