Skip to content

EN 2FA validator for Era #2037

Open
vladbochok wants to merge 12 commits intodraft-v31from
vb-validator-2fa-era
Open

EN 2FA validator for Era #2037
vladbochok wants to merge 12 commits intodraft-v31from
vb-validator-2fa-era

Conversation

@vladbochok
Copy link
Member

@vladbochok vladbochok commented Feb 16, 2026

What ❔

  • EraMultisigValidator - intermediate contract that validates multisig signatures of 2FA External Nodes for state transition. Designed for Era chains.
  • No changes are required for the EN, only stand-alone tool is needed to sign batches.

Why ❔

Checklist

  • [ x PR title corresponds to the body of PR (we generate changelog entries from PRs).
  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4b92171a2e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a two-factor authentication (2FA) mechanism for Era chain validators by adding an EraMultisigValidator contract that wraps the existing ValidatorTimelock. The new contract requires a configurable threshold of multisig member approvals before batch execution can proceed, providing an additional security layer where independent nodes verify execution parameters before state transitions are finalized on L1.

Changes:

  • Added EraMultisigValidator contract implementing multisig approval mechanism with EIP-712 typed signatures for batch execution
  • Added IEraMultisigValidator interface defining the multisig validator API
  • Modified ValidatorTimelock to make key functions virtual, enabling inheritance and overriding
  • Added comprehensive test suite covering initialization, threshold management, membership changes, approval workflows, and batch execution scenarios

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
EraMultisigValidator.sol Core implementation of the multisig validator with approval tracking, threshold checking, and call forwarding to ValidatorTimelock
IEraMultisigValidator.sol Interface defining events, errors, and functions for the multisig validator
ValidatorTimelock.sol Modified to make precommitSharedBridge, revertBatchesSharedBridge, proveBatchesSharedBridge, and executeBatchesSharedBridge virtual to enable overriding
EraMultisigValidator.t.sol Comprehensive test suite with 40+ test cases covering all functionality including edge cases

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@vladbochok vladbochok changed the title Vb validator 2fa era EN 2FA validator for Era Feb 18, 2026
vladbochok and others added 6 commits February 18, 2026 11:48
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

/// @dev Shared initialization logic for EIP-712 and the validator timelock address.
function _initializeEraMultisig(address _validatorTimelock) internal {
__EIP712_init("EraMultisigValidator", "1");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment

@github-actions
Copy link
Contributor

Coverage after merging vb-validator-2fa-era into draft-v31 will be

91.31%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
contracts/bridge
   BridgeHelper.sol100%100%100%100%
   BridgedStandardERC20.sol96.25%100%92.31%97.01%231–232
   L1ERC20Bridge.sol97.78%100%100%97.30%261
   L1Nullifier.sol95.98%100%100%95.24%432–433, 436, 462, 710, 713, 715, 731
   UpgradeableBeaconDeployer.sol100%100%100%100%
contracts/bridge/asset-router
   AssetRouterBase.sol98.53%100%100%98.21%128
   L1AssetRouter.sol91.62%100%86.67%92.70%104, 319, 330, 412–413, 432, 590, 601, 615, 620
contracts/bridge/asset-tracker
   AssetTrackerBase.sol93.55%100%88.89%95.45%84
   GWAssetTracker.sol89.82%100%94.59%89.08%105–107, 109–111, 124–125, 262–264, 280, 370, 411, 413–419, 426–427, 647–648, 93
   L1AssetTracker.sol97.95%100%100%97.60%226, 404, 61
   LegacySharedBridgeAddresses.sol83.33%100%100%81.82%39, 41
contracts/bridge/interfaces
   AssetHandlerModifiers.sol75%100%100%66.67%13
contracts/bridge/ntv
   L1NativeTokenVault.sol98.15%100%100%97.67%183, 185
   NativeTokenVaultBase.sol98.95%100%100%98.74%141, 146
contracts/common
   MessageVerification.sol88.24%100%87.50%88.46%34, 41–42
   ReentrancyGuard.sol100%100%100%100%
contracts/common/l2-helpers
   L2ContractHelper.sol98.11%100%100%97.78%108
   SystemContractsCaller.sol52.50%100%60%51.43%44–45, 47, 49, 51, 53, 66, 69, 72, 75, 78, 83, 89, 91, 93, 96, 98
contracts/common/libraries
   DataEncoding.sol95.61%100%95.65%95.60%183, 273, 291, 297
   DynamicIncrementalMerkle.sol100%100%100%100%
   DynamicIncrementalMerkleMemory.sol98.96%100%100%98.84%196
   FullMerkle.sol98.72%100%100%98.59%152
   FullMerkleMemory.sol93.81%100%100%93.33%114, 131, 149, 163, 194, 90
   Merkle.sol100%100%100%100%
   MessageHashing.sol98.67%100%100%98.46%154
   SemVer.sol100%100%100%100%
   UncheckedMath.sol100%100%100%100%
   UnsafeBytes.sol100%100%100%100%
   ZKSyncOSBytecodeInfo.sol100%100%100%100%
contracts/common/libraries/TransientPrimitives
   TransientPrimitives.sol100%100%100%100%
contracts/core/bridgehub
   BridgehubBase.sol96.86%100%100%96.23%136, 285, 301, 558, 562, 565
   L1Bridgehub.sol92.78%100%100%91.86%202, 277, 281–282, 285, 295, 85
   L2Bridgehub.sol66.67%100%60%68.57%103–104, 112, 114–115, 124, 129–130, 132–133, 76
contracts/core/chain-asset-handler
   ChainAssetHandlerBase.sol85.57%100%92.31%84.52%104–105, 123–125, 174, 177, 186–187, 320, 324, 346, 97
   L1ChainAssetHandler.sol91.86%100%87.50%92.86%255, 71–72, 76–77
   L2ChainAssetHandler.sol84.21%100%80%85.71%120, 124, 69, 93
contracts/core/chain-registration
   ChainRegistrationSender.sol88.24%100%100%85.19%41, 85, 89, 95
contracts/core/ctm-deployment
   CTMDeploymentTracker.sol100%100%100%100%
contracts/core/message-root
   L1MessageRoot.sol93.88%100%88.89%95%136–137
   L2MessageRoot.sol61.54%100%44.44%66.67%101, 108, 39–40, 45–46, 50, 57, 62–63
   MessageRootBase.sol93.52%100%100%92.31%119, 123, 187, 207, 290, 309, 345
contracts/governance
   AccessControlRestriction.sol100%100%100%100%
   ChainAdmin.sol97.87%100%100%97.30%39
   ChainAdminOwnable.sol100%100%100%100%
   Governance.sol100%100%100%100%
   L2ProxyAdminDeployer.sol100%100%100%100%
   PermanentRestriction.sol100%100%100%100%
   ServerNotifier.sol100%100%100%100%
   TransitionaryOwner.sol100%100%100%100%
contracts/governance/restriction
   Restriction.sol100%100%100%100%
   RestrictionValidator.sol100%100%100%100%
contracts/interop
   AttributesDecoder.sol100%100%100%100%
   InteropCenter.sol93.90%100%89.47%94.48%114, 428, 502, 54–55, 59–60, 72
   InteropDataEncoding.sol100%100%100%100%
   InteropHandler.sol91.53%100%83.33%92.45%33–35, 381, 403, 408, 41–42
   L2MessageVerification.sol100%100%100%100%
contracts/l2-system/zksync-os
   L1MessageGasLib.sol100%100%100%100%
   L1Messenger.sol94.12%100%100%92.86%29
   SystemContext.sol100%100%100%100%
   ZKOSContractDeployer.sol0%100%0%0%12–14, 20, 26, 30–31
contracts/l2-upgrades
   L2ComplexUpgrader.sol0%100%0%0%23–25, 39, 44, 46, 56, 62–63, 70, 79–81, 84, 86–87
   L2GenesisForceDeploymentsHelper.sol93.63%100%100%93.06%125, 171, 173, 177, 179–180, 210, 216, 425, 92
   L2GenesisUpgrade.sol0%100%0%0%30, 37, 39–40, 43, 47–50, 53, 55, 63
   L2V30TestnetSystemProxiesUpgrade.sol0%100%0%0%22, 27–28, 30, 41, 47, 52, 56, 61, 66, 71, 76, 81, 86, 93, 99
   L2V31Upgrade.sol0%100%0%0%17–18
   SystemContractProxy.sol88%100%66.67%90.91%16–17
   SystemContractProxyAdmin.sol60%100%66.67%57.14%12, 18–19
   V31AcrossRecovery.sol0%100%0%0%43–45, 64–65, 67–68, 72, 77–78, 93
contracts/state-transition
   AccessControlEnumerablePerChainAddressUpgradeable.sol98.25%100%100%97.83%179
   ChainTypeManagerBase.sol96.19%100%100%95.29%191, 194, 368, 458, 463, 605, 668, 706, 782
   EraChainTypeManager.sol92.86%100%100%91.67%29
   ZKsyncOSChainTypeManager.sol100%100%100%100%
contracts/state-transition/chain-deps
   DiamondInit.sol94.12%100%100%93.88%58, 62, 66
   DiamondProxy.sol100%100%100%100%
   StoredBatchHashing.sol100%100%100%100%
contracts/state-transition/chain-deps/facets
   Admin.sol96.12%100%100%95.48%137, 141, 145, 215, 240–241, 325, 364
   Committer.sol90.73%100%100%89.92%146, 171, 178, 224, 227–228, 232–233, 342, 371, 380–381, 390, 452, 479, 486–488, 515, 590, 601, 639, 715, 742
   Executor.sol77.69%100%91.67%76.15%105–107, 110, 112, 114–115, 117–118, 120, 160, 166–167, 177–179, 187, 245–246, 272, 277, 282,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants