Try   HackMD

EVM Script Factories for MEV Boost Allowed List

Introduction

The current doc describes the implementation details of EasyTrack EVM factories to manage an instance of the MEV Boost Relay Allowed List contract. Currently, the RMC committee holds the rights to manage the List directly. The proposed change will grant EasyTrack's EvmScriptExecutor the rights to modify the Allowed List via the introduced EVM script factories, while the RMC will retain the right to initiate EasyTrack motions.
The high-view overview of the management flow is presented in the below diagram.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Rights & Permissions

For the introduced EVM script factories to operate properly, it is required to set EasyTrack's EvmScriptExecutor as manager of the MEVBoostRelayAllowedList contract.

Role EVM Script Factory Methods
manager AddMEVBoostRelays add_relay
manager RemoveMEVBoostRelays remove_relay
manager EditMEVBoostRelays remove_relay, add_relay

Address can be set by calling the setManager method of the MEVBoostRelayAllowedList contract.

MEVBoostRelayAllowedList.set_manager(evmScriptExecutorAddress)

This method can be called only by the owner of the MEVBoostRelayAllowedList, which is a Lido Agent for the currently deployed instance.

IMEVBoostRelayAllowedList Interface

// SPDX-FileCopyrightText: 2025 Lido <info@lido.fi>
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.6;

/// @title Lido's MEV Boost Relay Allowed List interface
interface IMEVBoostRelayAllowedList {
    struct Relay {
        string uri;
        string operator;
        bool is_mandatory;
        string description;
    }

    // View Functions
    function get_relays_amount() external view returns (uint256);

    function get_relay_by_uri(string memory relay_uri) external view returns (Relay memory);

    // State-Changing Functions
    function add_relay(
        string memory uri,
        string memory operator,
        bool is_mandatory,
        string memory description
    ) external;

    function remove_relay(string memory uri) external;
}

Trade-offs

Transferring the manager role to the EvmScriptExecutor introduces a new constraint on Allowed List modifications. Direct modifications to the Allowed List through the MEVBoostRelayAllowedList contract will not be possible and all changes will be subject to a delay becasue of a mandatory objection period.

The current implementation of the EVM script factories does not support including multiple actions of different types in a single motion. For example, it is not possible to simultaneously add a relay and remove another one in one motion. To achieve the same results a separate motion must be created for each type of action performed on the Allowed List to be run in parallel.

Each factory validates the script against the state of the Allowed List at the time of script creation and again before execution upon motion enactment. If multiple motions modifying the same relays in conflicting ways are proposed in close succession, they may pass initial creation validation but fail at enactment. For example, if one motion is created to remove a relay and another to edit the same relay, both will initially validate successfully since the relay URI is still present in the list at the moment of their creation. However, if the removal motion is enacted first, the edit motion will fail at execution because the relay no longer exists in the list. This limitation should be carefully considered when creating motions to avoid unintended failures.

AddMEVBoostRelays

Allows creation of EVM script to add a set of MEV Boost Relays operators to the instance of the MEVBoostRelayAllowedList.

Data Types

No additional data types are required, using the struct from the Allowed List interface:

interface IMEVBoostRelayAllowedList {
    struct Relay {
        string uri;
        string operator;
        bool is_mandatory;
        string description;
    }
}

Immutable Variables

  • IMEVBoostRelayAllowedList mevBoostRelayAllowedList - address of the instance of the MEVBoostRelayAllowedList

Methods

createEVMScript(address,bytes)

  • Arguments:
    • address _creator - the creator of the EVM Script
    • bytes memory _evmScriptCallData - an ABI encoded array (IMEVBoostRelayAllowedList.Relay[] memory decodedCallData)
  • Visibility: external
  • Mutability: view
  • Modifiers: onlyTrustedCaller(_creator)
  • Returns: (bytes memory)

Creates an EVM script to add a list of relays to the instance of the MEVBoostRelayAllowedList.

This function will be called by the EasyTrack when the motion is created and then again when it is enacted.

To successfully create and enact motion, the following onchain requirements must be met:

  • Input data MUST not be empty
  • Input data MUST be decoded successfully into an array of IMEVBoostRelayAllowedList.Relay
  • The number of relays added MUST BE greater than 0
  • The total number of relays in the mevBoostRelayAllowedList instance, after adding the new ones, MUST NOT exceed MAX_NUM_RELAYS
  • Relays uris MUST NOT be empty
  • Relays uris and string parameters operator and description MUST NOT exceed the string length limit of 1024 characters
  • Relays uris MUST NOT have duplicates
  • Relays uris MUST NOT be already presented in the allow list contract.

decodeEVMScriptCallData(bytes)

  • Arguments:
    • bytes memory _evmScriptCallData - an ABI encoded array (IMEVBoostRelayAllowedList.Relay[])
  • Visibility: external
  • Mutability: pure
  • Returns: (IMEVBoostRelayAllowedList.Relay[] memory)

Decodes _evmScriptCallData into array (IMEVBoostRelayAllowedList.Relay[] relays).

RemoveMEVBoostRelays

Allows creation of EVM script to remove a set of MEV Boost Relays operators on the instance of the MEVBoostRelayAllowedList.

Data Types

As relays are identified by their URIs, the input data for each relay to be removed is simply a URI string, so no additional data types are required.

Immutable Variables

  • IMEVBoostRelayAllowedList mevBoostRelayAllowedList - address of the instance of the MEVBoostRelayAllowedList

Methods

createEVMScript(address,bytes)

  • Arguments:
    • address _creator - the creator of the EVM Script
    • bytes memory _evmScriptCallData - an ABI encoded array (string[] memory decodedCallData)
  • Visibility: external
  • Mutability: view
  • Modifiers: onlyTrustedCaller(_creator)
  • Returns: (bytes memory)

Creates an EVM script to remove a list of relays from the instance of the MEVBoostRelayAllowedList.

This function will be called by the EasyTrack when the motion is created and then again when it is enacted.

To successfully create and enact motion, the following onchain requirements must be met:

  • Input data MUST not be empty
  • Input data MUST be decoded successfully into an array of string
  • The number of relays removed MUST BE more than 0
  • Relays uris MUST NOT be empty
  • Relays uris MUST NOT have duplicates
  • Relays uris MUST be already presented in the allow list contract.

decodeEVMScriptCallData(bytes)

  • Arguments:
    • bytes memory _evmScriptCallData - an ABI encoded array (string[])
  • Visibility: external
  • Mutability: pure
  • Returns: (string[] memory)

Decodes _evmScriptCallData into array (string[] relayUris).

EditMEVBoostRelays

Allows creation of EVM script to edit a set of MEV Boost Relays operators on the instance of the MEVBoostRelayAllowedList.

Any existing relay can be edited by its URI, and the new data for the relay is provided in the input data.

Data Types

No additional data types are required, using the struct from the Allowed List interface:

interface IMEVBoostRelayAllowedList {
    struct Relay {
        string uri;
        string operator;
        bool is_mandatory;
        string description;
    }
}

Immutable Variables

  • IMEVBoostRelayAllowedList mevBoostRelayAllowedList - address of the instance of the MEVBoostRelayAllowedList

Methods

createEVMScript(address,bytes)

  • Arguments:
    • address _creator - the creator of the EVM Script
    • bytes memory _evmScriptCallData - an ABI encoded array (IMEVBoostRelayAllowedList.Relay[] memory decodedCallData)
  • Visibility: external
  • Mutability: view
  • Modifiers: onlyTrustedCaller(_creator)
  • Returns: (bytes memory)

Creates an EVM script to edit a list of relays on the instance of the MEVBoostRelayAllowedList.

This function will be called by the EasyTrack when the motion is created and then again when it is enacted.

Every portion of the data can be modified, except for URI which acts as a primary key.

MEV Boost Relay Allowed List contract does not have a method to directly edit a relay, so the edit operation is implemented as an ordered combination of remove_relay and add_relay operations in a single EVM script. The relay is removed as a first action, and then added with the new data. To ensure idempotency, same URI is used to create the relay as was used when removing it, which means that it's impossible to edit the URI (primary key) this way.

To successfully create and enact motion, the following onchain requirements must be met:

  • Input data MUST not be empty
  • Input data MUST be decoded successfully into an array of IMEVBoostRelayAllowedList.Relay
  • The number of relays edited MUST BE more than 0
  • Relays uris MUST NOT be empty
  • Relays uris and string parameters operator and description MUST NOT exceed the string length limit of 1024 characters
  • Relays uris MUST NOT have duplicates
  • Relays uris MUST be already presented in the allow list contract.

decodeEVMScriptCallData(bytes)

  • Arguments:
    • bytes memory _evmScriptCallData - an ABI encoded array (IMEVBoostRelayAllowedList.Relay[])
  • Visibility: external
  • Mutability: pure
  • Returns: (IMEVBoostRelayAllowedList.Relay[] memory)

Decodes _evmScriptCallData into array (IMEVBoostRelayAllowedList.Relay[] relays).

MEVBoostRelaysInputUtils Library

A library that encapsulates input validation logic and calldata decoding. Used by the EVM script factories internally to reduce code duplication.

Methods

validateRelays(Relay[],Relay[],bool)

  • Arguments:
    • IMEVBoostRelayAllowedList.Relay[] memory _relays - Array of Relay structs to validate
    • IMEVBoostRelayAllowedList.Relay[] memory _currentAllowedRelays - Current list of allowed relays from the MEVBoostRelayAllowedList contract
    • bool _expectExistence - Switches the expected existence of the relay URIs in the current relay list
      • if true, the relay URIs should exist in the current relay list and will revert otherwise
      • if false, the relay URIs should NOT exist in the current relay list and will revert otherwise
  • Visibility: internal
  • Mutability: pure
  • Returns: (bool)

Performs validation on an array of relay structs. Validates the relay parameters (URI, operator, and description), checks for duplicate input, and verifies the existence of relay URIs in the current relay list based on the _expectExistence flag.

validateRelayURIs(string[],Relay[])

  • Arguments:
    • string[] memory _relayURIs - Array of Relay URI strings to validate
    • IMEVBoostRelayAllowedList.Relay[] memory _currentAllowedRelays - Current list of allowed relays from the MEVBoostRelayAllowedList contract
  • Visibility: internal
  • Mutability: pure
  • Returns: (bool)

Performs validation on an array of relay URIs. Validates the URI length and presence, checks for duplicate input, and verifies the existence of relay URIs in the current relay list.

decodeCallDataWithRelayStructs(bytes)

  • Arguments:
    • bytes memory _evmScriptCallData - Encoded relay struct array
  • Visibility: internal
  • Mutability: pure
  • Returns: (IMEVBoostRelayAllowedList.Relay[] memory)

Decodes the call data for a relay struct array.

decodeCallDataWithRelayURIs(bytes)

  • Arguments:
    • bytes memory _evmScriptCallData - Encoded relay URI string array
  • Visibility: internal
  • Mutability: pure
  • Returns: (string[] memory)

Decodes the call data for a relay URI string array.

References