MetaMask Delegation Framework

repository·main·Indexed 42 days ago

https://github.com/metamask/delegation-framework

A suite of smart account tools (DeleGator) built on ERC-4337 and supporting EIP-7702. It allows users to securely delegate onchain capabilities to others offchain using Caveats and restricted permissions via a proxy-based architecture including DeleGator Proxy, Implementation, and Core components.

Tokens
11.8K
Snippets
19
Records
54
Agent score
48%

What's inside MetaMask Delegation Framework

  1. Overview of the MultiSigDeleGator smart contract

    main
    The MultiSigDeleGator is a Solidity smart contract that extends DeleGatorCore. It is designed to provide multi-signature based access control and delegation capabilities. In this contract, all signers are Externally Owned Accounts (EOAs). To execute a transaction, you must meet a minimum threshold of signatures, and all signatures must be provided in ascending order by the signer's address.
  2. Understand context switching in LogicalOrWrapperEnforcer

    main

    The LogicalOrWrapperEnforcer provides logical OR functionality for groups of enforcers. However, because it uses external calls (Address.functionCall) to invoke inner enforcers, it triggers a context switch.

    When an enforcer is called through a LogicalOrWrapperEnforcer, the msg.sender inside that enforcer changes from the DelegationManager to the LogicalOrWrapperEnforcer address. This causes enforcers that use msg.sender as a state key to operate within a different storage namespace.

  3. Understand Batch Execution Security Risks

    main

    The Delegation Framework uses an assembly-optimized decodeBatch function for gas efficiency. This function relies on length fields within the calldata structure to process an array of Execution structs. Because it trusts these length fields without extensive bounds checking for optimization, malformed calldata can lead to several security risks:

    1. Information Leakage: An earlier execution in a batch might read calldata intended for a later execution if the length fields are manipulated.
    2. Enhanced MEV Extraction: Malicious actors may be able to preview upcoming operations within a batch, leading to unfavorable execution orders.
    3. Front-running within Batch: Earlier executions could act on information gleaned from later executions, enabling sandwich attacks or price manipulation within a single batch.
  4. Understand the role of DeleGatorCore

    main
    DeleGatorCore defines the interface required for a DelegationManager to invoke an Execution on behalf of a delegator. It serves as the base interface for Smart Account (SCA) implementations that support delegation functionality. Note that DeleGatorCore does not implement the full ERC-7579 standard; it follows a partial implementation as detailed in the ERC-7579 Details documentation.
  5. How the redeemDelegations method works

    main

    The redeemDelegations method allows redeemers to execute actions (Execution) that are verified by the DelegationManager before calling executeFromExecutor on the root delegator.

    Key Requirements

    • Matching Manager: Delegations must be redeemed using the same DelegationManager that was used to create the delegation signature, otherwise the transaction will revert.
    • Delegator Permissions: Delegator accounts must permit the DelegationManager to call the executeFromExecutor function.
    • Ordering: Delegations in the input array must be ordered from leaf to root. The last delegation in the array must hold the root authority.

    Execution Lifecycle

    The manager follows this sequence:

    1. Consumes encoded delegation chains (Delegation[]).
    2. Validates msg.sender permissions.
    3. Validates offchain delegation signatures.
    4. Checks if any delegations are disabled.
    5. Ensures sufficient authority exists through the delegation chain.
    6. Calls beforeAllHook (leaf to root).
    7. Calls beforeHook for each individual execution (leaf to root).
    8. Performs the Execution via executeFromExecutor on the root delegator.
    9. Calls afterHook for each individual execution (root to leaf).
    10. Calls afterAllHook (root to leaf).
    // The method signature used for redemption
    function redeemDelegations(
        bytes[] calldata _permissionContexts,
        ModeCode[] _modes,
        bytes[] calldata _executionCallDatas
    ) external;
  6. Understand EIP-7702 Smart Contract Architecture

    main

    The Delegation Framework implements EIP-7702-compatible contracts, which allow an Externally Owned Account (EOA) to submit an authorization to map the contract code of an existing contract to that EOA.

    Unlike the previous UUPS proxy-based architecture used in DeleGatorCore, the EIP-7702 approach:

    • Does not support contract initialization.
    • Does not rely on UUPS-related code.
    • Allows the EOA to control the contract directly or via a privileged ERC-4337 EntryPoint.
  7. Understand the ERC-7579 partial implementation in DeleGator

    main

    The DelegationManager and DeleGatorCore contracts implement a subset of the ERC-7579 standard to facilitate the execution interface within DeleGator accounts. This implementation focuses on providing secure execution capabilities while omitting non-essential account management features.

    Integrated Execution Features

    • executeFromExecutor: Enables the DelegationManager to perform actions within DeleGator accounts with proper authorization. It will revert if an unsupported execution mode is requested.
    • execute: Authorizes the EntryPoint to perform actions within DeleGator accounts. It will revert if an unsupported execution mode is requested.
    • ModeCode: A mechanism to encode execution options, specifically:
      • callType: Defines if the execution is a single transaction or a batch of transactions. This allows users to bundle multiple transactions into a single delegation.
      • execType: Defines error handling behavior, allowing users to choose between reverting the entire execution on error or returning values even when errors occur.

    Unsupported Features

    To maintain focus on the delegation system, the following ERC-7579 features are not supported:

    • CALLTYPE_DELEGATECALL (Delegate Call)
    • Module installation and uninstallation
    • Hooks
    • accountIds
    • Components
  8. Manage signers in Hybrid DeleGator

    main

    The HybridDeleGator allows for flexible signer management with the following rules and capabilities:

    • Signer Requirements: There must always be at least one active signer (either EOA or P256). While multiple signers can be added, only one valid signature is required to authorize an action.
    • Replacement: You can use a specific function to completely replace all existing signers at once.
    • Granular Control: Specific functions are provided to add or remove individual signers.
    • Contract Ownership: While contracts can be set as the owner for delegation signature validation, they are not valid for UserOp validation.
  9. Understand P256 signature types in Hybrid DeleGator

    main

    The HybridDeleGator supports two types of P256 signatures. While both use the NIST P256 elliptic curve, they differ in how keys are managed and what data is signed:

    1. Raw P256: Signatures generated directly using the NIST P256 elliptic curve.
    2. WebAuthn P256: Signatures generated using the P-256 elliptic curve as part of the WebAuthn specification.

    Signature verification is handled via the SmoothCryptoLib contract. If the chain supports EIP-7212, the P256Verifier contract acts as a 'Progressive Precompile', forwarding calls to a precompiled version to reduce gas costs from approximately 330,000 to 3,000.

  10. Understand deterministic deployment via CREATE2

    main

    The framework uses Solidity's CREATE2 opcode to ensure deterministic deployment. This allows contracts to be deployed at the same address across different networks, provided the salt, bytecode, and deployer address remain identical.

    The deployment scripts use a predefined salt value: "GATOR".

    Salt Processing Logic:

    1. The string "GATOR" is retrieved.
    2. It is processed using abi.encodePacked to create a dynamic-length byte array.
    3. The result is cast to bytes32 to ensure a fixed-length representation.

    Solidity Implementation:

    bytes32 salt = bytes32(abi.encodePacked("GATOR"));
  11. How the DeleGator Smart Account architecture works

    main

    A DeleGator Smart Account is a 4337-compatible account designed for delegation. The architecture follows a proxy pattern to allow users to manage their accounts while delegating specific capabilities.

    Core Components:

    • DeleGator Proxy: The contract controlled by the end user. It uses a chosen implementation via an EIP-1967 proxy pattern.
    • DeleGator Implementation: The logic contract that defines how the DeleGator works. Users can migrate implementations as their needs change. Implementations must include a signature scheme for verifying access control.
    • DeleGator Core: Provides the underlying delegation execution and ERC-4337 functionality. There are two variants:
      • DeleGatorCore: Standard implementation.
      • EIP7702 DeleGator Core: Includes delegation and ERC-4337 functionality but excludes UUPS proxy functionalities.
    • Delegation Manager: The component responsible for validating and executing Delegations.
    • Caveat Enforcers: Contracts that manage Caveats (restrictions and rules). By default, a Delegation allows any onchain action, so Caveats are used to restrict functionality (e.g., limiting a delegate to spending only 100 USDC).
  12. Understand the Delegation redemption flow

    main

    The delegation lifecycle consists of an off-chain creation phase followed by an on-chain redemption phase managed by the DelegationManager.

    1. Off-chain Creation

    1. Delegator creates an off-chain delegation including specific caveat enforcers.
    2. Delegator signs the off-chain delegation.
    3. Delegator sends the signed delegation to the Delegate.
    4. Delegate holds the delegation until they are ready to redeem it.

    2. On-chain Redemption

    When the Delegate calls redeemDelegations() on the DelegationManager with the delegation and execution details, the following sequence occurs:

    1. Signature Validation: The DelegationManager verifies the signature via isValidSignature().
    2. Pre-execution Hooks: The DelegationManager triggers beforeAllHook() and beforeHook() on the CaveatEnforcer. These must not return errors.
    3. Execution: The DelegationManager calls executeFromExecutor() on the Delegator, who then performs the intended action.
    4. Post-execution Hooks: Upon successful execution, the DelegationManager triggers afterHook() and afterAllHook() on the CaveatEnforcer. These must also not return errors.