Skip to content

Pectra upgrade #115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Pectra upgrade #115

wants to merge 8 commits into from

Conversation

eladiosch
Copy link
Contributor

This Pull Request was made for mainly 2 different things:

  • Create a new flow to trigger validators exit from the Execution Layer: This is a new feature from EIP-7002 available due to the Pectra upgrade. Currently it's not possible to do this on production since we're waiting for Eigenlayer to deploy it
  • Remove enclave related flows as we want to remove REEF. This means all validators will have a 2 ETH bond. This implies some modifications in the PufferProtocol contract. The GuardianModule code won't be modified (to avoid re-deploying it). However some comments have been added to indicate the deprecated functions and variables

Currently this is a WIP. There are a couple of things left to do, basically:

  • Fix some remaining failing tests of PufferProtocol
  • Add some tests for the new flow

@@ -10,5 +10,4 @@ struct ValidatorKeyData {
bytes32 depositDataRoot;
bytes[] blsEncryptedPrivKeyShares;
bytes blsPubKeySet;
bytes raveEvidence;
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should rethink this one. If we remove it right now, and in the future we decide to add a new field to this struct, it might contain some bad data. This shouldn't be an issue, but it is still possible. I'd rather have it deprecated_raveEvidence or something like that just to eliminate that chance, even though it is minimal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines 11 to 12
bytes[] blsEncryptedPrivKeyShares;
bytes blsPubKeySet;
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can remove these two, they are related to enclave

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used deprecated_* as in prev comment

view
returns (bytes[] memory, bytes memory, uint256, uint256)
{
function getPayload(bytes32 moduleName) external view returns (bytes memory, uint256, uint256) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

99% sure that this was only used by the enclave, We can remove this function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

@bxmmm1
Copy link
Collaborator

bxmmm1 commented May 15, 2025

We can remove

        // Every guardian needs to receive a share
        if (data.blsEncryptedPrivKeyShares.length != GUARDIAN_MODULE.getGuardians().length) {
            revert InvalidBLSPrivateKeyShares();
        }

        // blsPubKeySet is for a subset of guardians and because of that we use .getThreshold()
        if (data.blsPubKeySet.length != (GUARDIAN_MODULE.getThreshold() * _BLS_PUB_KEY_LENGTH)) {
            revert InvalidBLSPublicKeySet();
        }

@bxmmm1
Copy link
Collaborator

bxmmm1 commented May 15, 2025

It would be nice if we introduced 2 ways of doing execution layer withdrawals/exits

Way 1:
PufferProtocol (validate that the node operator that registered a validator is doing the request) -> PMM -> Module -> Eigenpod

In this flow, if the validator is 0x02, the same function could be used to withdraw the rewards from beacon chain
protocol.

something like:

    PufferProtocool.requestWithdrawal(bytes[] pubkeys, uint256[] amounts) external {
        ProtocolStorage storage $ = _getPufferProtocolStorage();

        address node = $.nodeOperatorInfo[msg.sender].node;
 
        // validate pubkeys belong to that node
       // allow withdrawals from the same module? or figure out something

        PUFFER_MODULE_MANAGER.requestWithdrawal(pufferModule, pubkeys, amounts);
    }
    ```
    
in PMM `requestWithdrawal` can be called by puffer paymaster | pufferProtocol
    
If we need to exit validators, we call it from the paymaster, otherwise the users request rewards withdrawals/exit their validator from on-chain

Potential attack vector:
We provision 64 ETH Validator (2 VT per day), user requests a withdrawal of 32 ETH. This is not their reward, and the ETH should be returned to the Vault, a potential DOS attack is possible, if we give the ability to users to request withdrawals with any amount

wyt? should we sync on this more?
    

@eladiosch
Copy link
Contributor Author

We can remove

        // Every guardian needs to receive a share
        if (data.blsEncryptedPrivKeyShares.length != GUARDIAN_MODULE.getGuardians().length) {
            revert InvalidBLSPrivateKeyShares();
        }

        // blsPubKeySet is for a subset of guardians and because of that we use .getThreshold()
        if (data.blsPubKeySet.length != (GUARDIAN_MODULE.getThreshold() * _BLS_PUB_KEY_LENGTH)) {
            revert InvalidBLSPublicKeySet();
        }

Removed

@eladiosch
Copy link
Contributor Author

It would be nice if we introduced 2 ways of doing execution layer withdrawals/exits

Way 1: PufferProtocol (validate that the node operator that registered a validator is doing the request) -> PMM -> Module -> Eigenpod

In this flow, if the validator is 0x02, the same function could be used to withdraw the rewards from beacon chain protocol.

something like:

    PufferProtocool.requestWithdrawal(bytes[] pubkeys, uint256[] amounts) external {
        ProtocolStorage storage $ = _getPufferProtocolStorage();

        address node = $.nodeOperatorInfo[msg.sender].node;
 
        // validate pubkeys belong to that node
       // allow withdrawals from the same module? or figure out something

        PUFFER_MODULE_MANAGER.requestWithdrawal(pufferModule, pubkeys, amounts);
    }
    ```
    
in PMM `requestWithdrawal` can be called by puffer paymaster | pufferProtocol
    
If we need to exit validators, we call it from the paymaster, otherwise the users request rewards withdrawals/exit their validator from on-chain

Potential attack vector:
We provision 64 ETH Validator (2 VT per day), user requests a withdrawal of 32 ETH. This is not their reward, and the ETH should be returned to the Vault, a potential DOS attack is possible, if we give the ability to users to request withdrawals with any amount

wyt? should we sync on this more?
    

Since we're not adding support to 0x02 validators in this PR, and when we do we have to change more stuff I'd say to implement those changes in a future PR when we're sure on how will 0x02 validators will affect our architecture.

Also in my implementation, the PMM function can only be called from a new role ROLE_ID_VALIDATOR_EXITOR

We can sync on this if you want

Copy link

codecov bot commented May 16, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Files with missing lines Coverage Δ
mainnet-contracts/src/GuardianModule.sol 74.61% <ø> (-10.77%) ⬇️
mainnet-contracts/src/PufferModule.sol 100.00% <100.00%> (ø)
mainnet-contracts/src/PufferModuleManager.sol 92.00% <100.00%> (+0.95%) ⬆️
mainnet-contracts/src/PufferProtocol.sol 94.73% <100.00%> (+0.07%) ⬆️

... and 7 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@eladiosch eladiosch marked this pull request as ready for review May 16, 2025 16:15
event ValidatorKeyRegistered(
bytes pubKey, uint256 indexed pufferModuleIndex, bytes32 indexed moduleName, bool usingEnclave
);
event ValidatorKeyRegistered(bytes pubKey, uint256 indexed pufferModuleIndex, bytes32 indexed moduleName);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This changes the event signature, if we want to have it easy on the off-chain side(subgraph), we can keep the old event signature and always emit false for usingEnclave. IMO, it is not a big deal to change it as well, but it is something we must be aware of.

@bxmmm1
Copy link
Collaborator

bxmmm1 commented May 20, 2025

It would be nice if we introduced 2 ways of doing execution layer withdrawals/exits
Way 1: PufferProtocol (validate that the node operator that registered a validator is doing the request) -> PMM -> Module -> Eigenpod
In this flow, if the validator is 0x02, the same function could be used to withdraw the rewards from beacon chain protocol.
something like:

    PufferProtocool.requestWithdrawal(bytes[] pubkeys, uint256[] amounts) external {
        ProtocolStorage storage $ = _getPufferProtocolStorage();

        address node = $.nodeOperatorInfo[msg.sender].node;
 
        // validate pubkeys belong to that node
       // allow withdrawals from the same module? or figure out something

        PUFFER_MODULE_MANAGER.requestWithdrawal(pufferModule, pubkeys, amounts);
    }
    ```
    
in PMM `requestWithdrawal` can be called by puffer paymaster | pufferProtocol
    
If we need to exit validators, we call it from the paymaster, otherwise the users request rewards withdrawals/exit their validator from on-chain

Potential attack vector:
We provision 64 ETH Validator (2 VT per day), user requests a withdrawal of 32 ETH. This is not their reward, and the ETH should be returned to the Vault, a potential DOS attack is possible, if we give the ability to users to request withdrawals with any amount

wyt? should we sync on this more?
    

Since we're not adding support to 0x02 validators in this PR, and when we do we have to change more stuff I'd say to implement those changes in a future PR when we're sure on how will 0x02 validators will affect our architecture.

Also in my implementation, the PMM function can only be called from a new role ROLE_ID_VALIDATOR_EXITOR

We can sync on this if you want

overall, the PR looks good. Lets sync on this topic tomorrow. Would be nice to bundle a few things in one audit, and have 1 upgrade instead of more.

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.

2 participants