AVSRegistrar

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "src/AVSRegistrar.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import { IAllocationManager } from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import { IKeyRegistrar } from "eigenlayer-contracts/src/contracts/interfaces/IKeyRegistrar.sol";
import { IPermissionController } from "eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol";
import {
    AVSRegistrarStorage,
    IAVSRegistrar,
    OperatorSet
} from "eigenlayer-middleware/src/middlewareV2/registrar/AVSRegistrar.sol";

import { Allowlist } from "eigenlayer-middleware/src/middlewareV2/registrar/modules/Allowlist.sol";
import { SocketRegistry } from "eigenlayer-middleware/src/middlewareV2/registrar/modules/SocketRegistry.sol";

contract AVSRegistrar is SocketRegistry, Allowlist, AVSRegistrarStorage {
    modifier onlyAllocationManager() {
        require(msg.sender == address(allocationManager), NotAllocationManager());
        _;
    }

    constructor(
        IAllocationManager _allocationManager,
        IPermissionController _permissionController,
        IKeyRegistrar _keyRegistrar
    ) AVSRegistrarStorage(_allocationManager, _keyRegistrar) SocketRegistry(_permissionController) {
        _disableInitializers();
    }

    function initialize(address admin, string memory metadataURI) public initializer {
        // Set the owner for allowlist management
        __Allowlist_init(admin);
        __AVSRegistrar_init(address(this));
        // Set the metadataURI and the registrar for the AVS to this contract
        allocationManager.updateAVSMetadataURI(address(this), metadataURI);
        allocationManager.setAVSRegistrar(address(this), this);
        // Set the admin for the AVS
        permissionController.addPendingAdmin(address(this), admin);
    }

    /// @inheritdoc IAVSRegistrar
    /// @dev Reverts for:
    ///      - NotAllocationManager: The caller is not the allocation manager
    ///      - KeyNotRegistered: The operator has not registered a key for the given operator sets in the `KeyRegistrar`
    function registerOperator(
        address operator,
        address, /* avs */
        uint32[] calldata operatorSetIds,
        bytes calldata data
    ) external virtual onlyAllocationManager {
        _beforeRegisterOperator(operator, operatorSetIds, data);

        // Check that the operator has a valid key
        _validateOperatorKeys(operator, operatorSetIds);

        _afterRegisterOperator(operator, operatorSetIds, data);

        emit OperatorRegistered(operator, operatorSetIds);
    }

    /// @inheritdoc IAVSRegistrar
    /// @dev Reverts for:
    ///      - NotAllocationManager: The caller is not the allocation manager
    function deregisterOperator(
        address operator,
        address, /* avs */
        uint32[] calldata operatorSetIds
    ) external virtual onlyAllocationManager {
        _beforeDeregisterOperator(operator, operatorSetIds);

        _afterDeregisterOperator(operator, operatorSetIds);

        emit OperatorDeregistered(operator, operatorSetIds);
    }

    /// @inheritdoc IAVSRegistrar
    function supportsAVS(
        address _avs
    ) public view virtual returns (bool) {
        return _avs == avs;
    }

    /*
     *
     *                            INTERNAL FUNCTIONS
     *
     */

    /// @dev This initialization function MUST be added to a child's `initialize` function to avoid uninitialized storage.
    function __AVSRegistrar_init(
        address _avs
    ) internal virtual onlyInitializing {
        avs = _avs;
    }

    /**
     * @notice Validates that the operator has registered a key for the given operator sets in the `KeyRegistrar`
     * @param operator The operator to validate
     * @param operatorSetIds The operator sets to validate
     * @dev Reverts for:
     *      - KeyNotRegistered: The operator has not registered a key for the given operator sets in the `KeyRegistrar`
     */
    function _validateOperatorKeys(address operator, uint32[] calldata operatorSetIds) internal view {
        for (uint32 i = 0; i < operatorSetIds.length; i++) {
            OperatorSet memory operatorSet = OperatorSet({ avs: avs, id: operatorSetIds[i] });
            require(keyRegistrar.isRegistered(operatorSet, operator), KeyNotRegistered());
        }
    }

    /**
     * @notice Hook called before the operator is registered
     * @param operator The operator to register
     * @param operatorSetIds The operator sets to register
     * @param data The data to register
     */
    function _beforeRegisterOperator(
        address operator,
        uint32[] calldata operatorSetIds,
        bytes calldata data
    ) internal virtual {
        // Check that the operator is in the allowlist
        for (uint32 i; i < operatorSetIds.length; ++i) {
            require(
                isOperatorAllowed(OperatorSet({ avs: avs, id: operatorSetIds[i] }), operator), OperatorNotInAllowlist()
            );
        }
    }

    /**
     * @notice Hook called after the operator is registered
     * @param operator The operator to register
     * @param operatorSetIds The operator sets to register
     * @param data The data to register
     */
    function _afterRegisterOperator(
        address operator,
        uint32[] calldata operatorSetIds,
        bytes calldata data
    ) internal virtual {
        // Set operator socket
        string memory socket = abi.decode(data, (string));
        _setOperatorSocket(operator, socket);
    }

    /**
     * @notice Hook called before the operator is deregistered
     * @param operator The operator to deregister
     * @param operatorSetIds The operator sets to deregister
     */
    function _beforeDeregisterOperator(address operator, uint32[] calldata operatorSetIds) internal virtual { }

    /**
     * @notice Hook called after the operator is deregistered
     * @param operator The operator to deregister
     * @param operatorSetIds The operator sets to deregister
     */
    function _afterDeregisterOperator(address operator, uint32[] calldata operatorSetIds) internal virtual { }
}
"
    },
    "lib/rxp/contracts/lib/eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.5.0;

import {OperatorSet} from "../libraries/OperatorSetLib.sol";
import "./IPauserRegistry.sol";
import "./IStrategy.sol";
import "./IAVSRegistrar.sol";
import "./ISemVerMixin.sol";

interface IAllocationManagerErrors {
    /// Input Validation

    /// @dev Thrown when `wadToSlash` is zero or greater than 1e18
    error InvalidWadToSlash();
    /// @dev Thrown when two array parameters have mismatching lengths.
    error InputArrayLengthMismatch();
    /// @dev Thrown when the AVSRegistrar is not correctly configured to prevent an AVSRegistrar contract
    /// from being used with the wrong AVS
    error InvalidAVSRegistrar();
    /// @dev Thrown when an invalid strategy is provided.
    error InvalidStrategy();
    /// @dev Thrown when an invalid redistribution recipient is provided.
    error InvalidRedistributionRecipient();

    /// Caller

    /// @dev Thrown when caller is not authorized to call a function.
    error InvalidCaller();

    /// Operator Status

    /// @dev Thrown when an invalid operator is provided.
    error InvalidOperator();
    /// @dev Thrown when an invalid avs whose metadata is not registered is provided.
    error NonexistentAVSMetadata();
    /// @dev Thrown when an operator's allocation delay has yet to be set.
    error UninitializedAllocationDelay();
    /// @dev Thrown when attempting to slash an operator when they are not slashable.
    error OperatorNotSlashable();
    /// @dev Thrown when trying to add an operator to a set they are already a member of
    error AlreadyMemberOfSet();
    /// @dev Thrown when trying to slash/remove an operator from a set they are not a member of
    error NotMemberOfSet();

    /// Operator Set Status

    /// @dev Thrown when an invalid operator set is provided.
    error InvalidOperatorSet();
    /// @dev Thrown when provided `strategies` are not in ascending order.
    error StrategiesMustBeInAscendingOrder();
    /// @dev Thrown when trying to add a strategy to an operator set that already contains it.
    error StrategyAlreadyInOperatorSet();
    /// @dev Thrown when a strategy is referenced that does not belong to an operator set.
    error StrategyNotInOperatorSet();

    /// Modifying Allocations

    /// @dev Thrown when an operator attempts to set their allocation for an operatorSet to the same value
    error SameMagnitude();
    /// @dev Thrown when an allocation is attempted for a given operator when they have pending allocations or deallocations.
    error ModificationAlreadyPending();
    /// @dev Thrown when an allocation is attempted that exceeds a given operators total allocatable magnitude.
    error InsufficientMagnitude();
}

interface IAllocationManagerTypes {
    /**
     * @notice Defines allocation information from a strategy to an operator set, for an operator
     * @param currentMagnitude the current magnitude allocated from the strategy to the operator set
     * @param pendingDiff a pending change in magnitude, if it exists (0 otherwise)
     * @param effectBlock the block at which the pending magnitude diff will take effect
     */
    struct Allocation {
        uint64 currentMagnitude;
        int128 pendingDiff;
        uint32 effectBlock;
    }

    /**
     * @notice Struct containing allocation delay metadata for a given operator.
     * @param delay Current allocation delay
     * @param isSet Whether the operator has initially set an allocation delay. Note that this could be false but the
     * block.number >= effectBlock in which we consider their delay to be configured and active.
     * @param pendingDelay The delay that will take effect after `effectBlock`
     * @param effectBlock The block number after which a pending delay will take effect
     */
    struct AllocationDelayInfo {
        uint32 delay;
        bool isSet;
        uint32 pendingDelay;
        uint32 effectBlock;
    }

    /**
     * @notice Contains registration details for an operator pertaining to an operator set
     * @param registered Whether the operator is currently registered for the operator set
     * @param slashableUntil If the operator is not registered, they are still slashable until
     * this block is reached.
     */
    struct RegistrationStatus {
        bool registered;
        uint32 slashableUntil;
    }

    /**
     * @notice Contains allocation info for a specific strategy
     * @param maxMagnitude the maximum magnitude that can be allocated between all operator sets
     * @param encumberedMagnitude the currently-allocated magnitude for the strategy
     */
    struct StrategyInfo {
        uint64 maxMagnitude;
        uint64 encumberedMagnitude;
    }

    /**
     * @notice Struct containing parameters to slashing
     * @param operator the address to slash
     * @param operatorSetId the ID of the operatorSet the operator is being slashed on behalf of
     * @param strategies the set of strategies to slash
     * @param wadsToSlash the parts in 1e18 to slash, this will be proportional to the operator's
     * slashable stake allocation for the operatorSet
     * @param description the description of the slashing provided by the AVS for legibility
     */
    struct SlashingParams {
        address operator;
        uint32 operatorSetId;
        IStrategy[] strategies;
        uint256[] wadsToSlash;
        string description;
    }

    /**
     * @notice struct used to modify the allocation of slashable magnitude to an operator set
     * @param operatorSet the operator set to modify the allocation for
     * @param strategies the strategies to modify allocations for
     * @param newMagnitudes the new magnitude to allocate for each strategy to this operator set
     */
    struct AllocateParams {
        OperatorSet operatorSet;
        IStrategy[] strategies;
        uint64[] newMagnitudes;
    }

    /**
     * @notice Parameters used to register for an AVS's operator sets
     * @param avs the AVS being registered for
     * @param operatorSetIds the operator sets within the AVS to register for
     * @param data extra data to be passed to the AVS to complete registration
     */
    struct RegisterParams {
        address avs;
        uint32[] operatorSetIds;
        bytes data;
    }

    /**
     * @notice Parameters used to deregister from an AVS's operator sets
     * @param operator the operator being deregistered
     * @param avs the avs being deregistered from
     * @param operatorSetIds the operator sets within the AVS being deregistered from
     */
    struct DeregisterParams {
        address operator;
        address avs;
        uint32[] operatorSetIds;
    }

    /**
     * @notice Parameters used by an AVS to create new operator sets
     * @param operatorSetId the id of the operator set to create
     * @param strategies the strategies to add as slashable to the operator set
     */
    struct CreateSetParams {
        uint32 operatorSetId;
        IStrategy[] strategies;
    }
}

interface IAllocationManagerEvents is IAllocationManagerTypes {
    /// @notice Emitted when operator updates their allocation delay.
    event AllocationDelaySet(address operator, uint32 delay, uint32 effectBlock);

    /// @notice Emitted when an operator's magnitude is updated for a given operatorSet and strategy
    event AllocationUpdated(
        address operator, OperatorSet operatorSet, IStrategy strategy, uint64 magnitude, uint32 effectBlock
    );

    /// @notice Emitted when operator's encumbered magnitude is updated for a given strategy
    event EncumberedMagnitudeUpdated(address operator, IStrategy strategy, uint64 encumberedMagnitude);

    /// @notice Emitted when an operator's max magnitude is updated for a given strategy
    event MaxMagnitudeUpdated(address operator, IStrategy strategy, uint64 maxMagnitude);

    /// @notice Emitted when an operator is slashed by an operator set for a strategy
    /// `wadSlashed` is the proportion of the operator's total delegated stake that was slashed
    event OperatorSlashed(
        address operator, OperatorSet operatorSet, IStrategy[] strategies, uint256[] wadSlashed, string description
    );

    /// @notice Emitted when an AVS configures the address that will handle registration/deregistration
    event AVSRegistrarSet(address avs, IAVSRegistrar registrar);

    /// @notice Emitted when an AVS updates their metadata URI (Uniform Resource Identifier).
    /// @dev The URI is never stored; it is simply emitted through an event for off-chain indexing.
    event AVSMetadataURIUpdated(address indexed avs, string metadataURI);

    /// @notice Emitted when an operator set is created by an AVS.
    event OperatorSetCreated(OperatorSet operatorSet);

    /// @notice Emitted when an operator is added to an operator set.
    event OperatorAddedToOperatorSet(address indexed operator, OperatorSet operatorSet);

    /// @notice Emitted when an operator is removed from an operator set.
    event OperatorRemovedFromOperatorSet(address indexed operator, OperatorSet operatorSet);

    /// @notice Emitted when a redistributing operator set is created by an AVS.
    event RedistributionAddressSet(OperatorSet operatorSet, address redistributionRecipient);

    /// @notice Emitted when a strategy is added to an operator set.
    event StrategyAddedToOperatorSet(OperatorSet operatorSet, IStrategy strategy);

    /// @notice Emitted when a strategy is removed from an operator set.
    event StrategyRemovedFromOperatorSet(OperatorSet operatorSet, IStrategy strategy);
}

interface IAllocationManager is IAllocationManagerErrors, IAllocationManagerEvents, ISemVerMixin {
    /**
     * @dev Initializes the initial owner and paused status.
     */
    function initialize(
        uint256 initialPausedStatus
    ) external;

    /**
     * @notice Called by an AVS to slash an operator in a given operator set. The operator must be registered
     * and have slashable stake allocated to the operator set.
     *
     * @param avs The AVS address initiating the slash.
     * @param params The slashing parameters, containing:
     *  - operator: The operator to slash.
     *  - operatorSetId: The ID of the operator set the operator is being slashed from.
     *  - strategies: Array of strategies to slash allocations from (must be in ascending order).
     *  - wadsToSlash: Array of proportions to slash from each strategy (must be between 0 and 1e18).
     *  - description: Description of why the operator was slashed.
     *
     * @return slashId The ID of the slash.
     * @return shares The amount of shares that were slashed for each strategy.
     *
     * @dev For each strategy:
     *      1. Reduces the operator's current allocation magnitude by wadToSlash proportion.
     *      2. Reduces the strategy's max and encumbered magnitudes proportionally.
     *      3. If there is a pending deallocation, reduces it proportionally.
     *      4. Updates the operator's shares in the DelegationManager.
     *
     * @dev Small slashing amounts may not result in actual token burns due to
     *      rounding, which will result in small amounts of tokens locked in the contract
     *      rather than fully burning through the burn mechanism.
     */
    function slashOperator(
        address avs,
        SlashingParams calldata params
    ) external returns (uint256 slashId, uint256[] memory shares);

    /**
     * @notice Modifies the proportions of slashable stake allocated to an operator set from a list of strategies
     * Note that deallocations remain slashable for DEALLOCATION_DELAY blocks therefore when they are cleared they may
     * free up less allocatable magnitude than initially deallocated.
     * @param operator the operator to modify allocations for
     * @param params array of magnitude adjustments for one or more operator sets
     * @dev Updates encumberedMagnitude for the updated strategies
     */
    function modifyAllocations(address operator, AllocateParams[] calldata params) external;

    /**
     * @notice This function takes a list of strategies and for each strategy, removes from the deallocationQueue
     * all clearable deallocations up to max `numToClear` number of deallocations, updating the encumberedMagnitude
     * of the operator as needed.
     *
     * @param operator address to clear deallocations for
     * @param strategies a list of strategies to clear deallocations for
     * @param numToClear a list of number of pending deallocations to clear for each strategy
     *
     * @dev can be called permissionlessly by anyone
     */
    function clearDeallocationQueue(
        address operator,
        IStrategy[] calldata strategies,
        uint16[] calldata numToClear
    ) external;

    /**
     * @notice Allows an operator to register for one or more operator sets for an AVS. If the operator
     * has any stake allocated to these operator sets, it immediately becomes slashable.
     * @dev After registering within the ALM, this method calls the AVS Registrar's `IAVSRegistrar.
     * registerOperator` method to complete registration. This call MUST succeed in order for
     * registration to be successful.
     */
    function registerForOperatorSets(address operator, RegisterParams calldata params) external;

    /**
     * @notice Allows an operator or AVS to deregister the operator from one or more of the AVS's operator sets.
     * If the operator has any slashable stake allocated to the AVS, it remains slashable until the
     * DEALLOCATION_DELAY has passed.
     * @dev After deregistering within the ALM, this method calls the AVS Registrar's `IAVSRegistrar.
     * deregisterOperator` method to complete deregistration. This call MUST succeed in order for
     * deregistration to be successful.
     */
    function deregisterFromOperatorSets(
        DeregisterParams calldata params
    ) external;

    /**
     * @notice Called by the delegation manager OR an operator to set an operator's allocation delay.
     * This is set when the operator first registers, and is the number of blocks between an operator
     * allocating magnitude to an operator set, and the magnitude becoming slashable.
     * @param operator The operator to set the delay on behalf of.
     * @param delay the allocation delay in blocks
     */
    function setAllocationDelay(address operator, uint32 delay) external;

    /**
     * @notice Called by an AVS to configure the address that is called when an operator registers
     * or is deregistered from the AVS's operator sets. If not set (or set to 0), defaults
     * to the AVS's address.
     * @param registrar the new registrar address
     */
    function setAVSRegistrar(address avs, IAVSRegistrar registrar) external;

    /**
     *  @notice Called by an AVS to emit an `AVSMetadataURIUpdated` event indicating the information has updated.
     *
     *  @param metadataURI The URI for metadata associated with an AVS.
     *
     *  @dev Note that the `metadataURI` is *never stored* and is only emitted in the `AVSMetadataURIUpdated` event.
     */
    function updateAVSMetadataURI(address avs, string calldata metadataURI) external;

    /**
     * @notice Allows an AVS to create new operator sets, defining strategies that the operator set uses
     */
    function createOperatorSets(address avs, CreateSetParams[] calldata params) external;

    /**
     * @notice Allows an AVS to create new Redistribution operator sets.
     * @param avs The AVS creating the new operator sets.
     * @param params An array of operator set creation parameters.
     * @param redistributionRecipients An array of addresses that will receive redistributed funds when operators are slashed.
     * @dev Same logic as `createOperatorSets`, except `redistributionRecipients` corresponding to each operator set are stored.
     *      Additionally, emits `RedistributionOperatorSetCreated` event instead of `OperatorSetCreated` for each created operator set.
     */
    function createRedistributingOperatorSets(
        address avs,
        CreateSetParams[] calldata params,
        address[] calldata redistributionRecipients
    ) external;

    /**
     * @notice Allows an AVS to add strategies to an operator set
     * @dev Strategies MUST NOT already exist in the operator set
     * @dev If the operatorSet is redistributing, the `BEACONCHAIN_ETH_STRAT` may not be added, since redistribution is not supported for native eth
     * @param avs the avs to set strategies for
     * @param operatorSetId the operator set to add strategies to
     * @param strategies the strategies to add
     */
    function addStrategiesToOperatorSet(address avs, uint32 operatorSetId, IStrategy[] calldata strategies) external;

    /**
     * @notice Allows an AVS to remove strategies from an operator set
     * @dev Strategies MUST already exist in the operator set
     * @param avs the avs to remove strategies for
     * @param operatorSetId the operator set to remove strategies from
     * @param strategies the strategies to remove
     */
    function removeStrategiesFromOperatorSet(
        address avs,
        uint32 operatorSetId,
        IStrategy[] calldata strategies
    ) external;

    /**
     *
     *                         VIEW FUNCTIONS
     *
     */

    /**
     * @notice Returns the number of operator sets for the AVS
     * @param avs the AVS to query
     */
    function getOperatorSetCount(
        address avs
    ) external view returns (uint256);

    /**
     * @notice Returns the list of operator sets the operator has current or pending allocations/deallocations in
     * @param operator the operator to query
     * @return the list of operator sets the operator has current or pending allocations/deallocations in
     */
    function getAllocatedSets(
        address operator
    ) external view returns (OperatorSet[] memory);

    /**
     * @notice Returns the list of strategies an operator has current or pending allocations/deallocations from
     * given a specific operator set.
     * @param operator the operator to query
     * @param operatorSet the operator set to query
     * @return the list of strategies
     */
    function getAllocatedStrategies(
        address operator,
        OperatorSet memory operatorSet
    ) external view returns (IStrategy[] memory);

    /**
     * @notice Returns the current/pending stake allocation an operator has from a strategy to an operator set
     * @param operator the operator to query
     * @param operatorSet the operator set to query
     * @param strategy the strategy to query
     * @return the current/pending stake allocation
     */
    function getAllocation(
        address operator,
        OperatorSet memory operatorSet,
        IStrategy strategy
    ) external view returns (Allocation memory);

    /**
     * @notice Returns the current/pending stake allocations for multiple operators from a strategy to an operator set
     * @param operators the operators to query
     * @param operatorSet the operator set to query
     * @param strategy the strategy to query
     * @return each operator's allocation
     */
    function getAllocations(
        address[] memory operators,
        OperatorSet memory operatorSet,
        IStrategy strategy
    ) external view returns (Allocation[] memory);

    /**
     * @notice Given a strategy, returns a list of operator sets and corresponding stake allocations.
     * @dev Note that this returns a list of ALL operator sets the operator has allocations in. This means
     * some of the returned allocations may be zero.
     * @param operator the operator to query
     * @param strategy the strategy to query
     * @return the list of all operator sets the operator has allocations for
     * @return the corresponding list of allocations from the specific `strategy`
     */
    function getStrategyAllocations(
        address operator,
        IStrategy strategy
    ) external view returns (OperatorSet[] memory, Allocation[] memory);

    /**
     * @notice For a strategy, get the amount of magnitude that is allocated across one or more operator sets
     * @param operator the operator to query
     * @param strategy the strategy to get allocatable magnitude for
     * @return currently allocated magnitude
     */
    function getEncumberedMagnitude(address operator, IStrategy strategy) external view returns (uint64);

    /**
     * @notice For a strategy, get the amount of magnitude not currently allocated to any operator set
     * @param operator the operator to query
     * @param strategy the strategy to get allocatable magnitude for
     * @return magnitude available to be allocated to an operator set
     */
    function getAllocatableMagnitude(address operator, IStrategy strategy) external view returns (uint64);

    /**
     * @notice Returns the maximum magnitude an operator can allocate for the given strategy
     * @dev The max magnitude of an operator starts at WAD (1e18), and is decreased anytime
     * the operator is slashed. This value acts as a cap on the max magnitude of the operator.
     * @param operator the operator to query
     * @param strategy the strategy to get the max magnitude for
     * @return the max magnitude for the strategy
     */
    function getMaxMagnitude(address operator, IStrategy strategy) external view returns (uint64);

    /**
     * @notice Returns the maximum magnitude an operator can allocate for the given strategies
     * @dev The max magnitude of an operator starts at WAD (1e18), and is decreased anytime
     * the operator is slashed. This value acts as a cap on the max magnitude of the operator.
     * @param operator the operator to query
     * @param strategies the strategies to get the max magnitudes for
     * @return the max magnitudes for each strategy
     */
    function getMaxMagnitudes(
        address operator,
        IStrategy[] calldata strategies
    ) external view returns (uint64[] memory);

    /**
     * @notice Returns the maximum magnitudes each operator can allocate for the given strategy
     * @dev The max magnitude of an operator starts at WAD (1e18), and is decreased anytime
     * the operator is slashed. This value acts as a cap on the max magnitude of the operator.
     * @param operators the operators to query
     * @param strategy the strategy to get the max magnitudes for
     * @return the max magnitudes for each operator
     */
    function getMaxMagnitudes(
        address[] calldata operators,
        IStrategy strategy
    ) external view returns (uint64[] memory);

    /**
     * @notice Returns the maximum magnitude an operator can allocate for the given strategies
     * at a given block number
     * @dev The max magnitude of an operator starts at WAD (1e18), and is decreased anytime
     * the operator is slashed. This value acts as a cap on the max magnitude of the operator.
     * @param operator the operator to query
     * @param strategies the strategies to get the max magnitudes for
     * @param blockNumber the blockNumber at which to check the max magnitudes
     * @return the max magnitudes for each strategy
     */
    function getMaxMagnitudesAtBlock(
        address operator,
        IStrategy[] calldata strategies,
        uint32 blockNumber
    ) external view returns (uint64[] memory);

    /**
     * @notice Returns the time in blocks between an operator allocating slashable magnitude
     * and the magnitude becoming slashable. If the delay has not been set, `isSet` will be false.
     * @dev The operator must have a configured delay before allocating magnitude
     * @param operator The operator to query
     * @return isSet Whether the operator has configured a delay
     * @return delay The time in blocks between allocating magnitude and magnitude becoming slashable
     */
    function getAllocationDelay(
        address operator
    ) external view returns (bool isSet, uint32 delay);

    /**
     * @notice Returns the number of blocks between an operator deallocating magnitude and the magnitude becoming
     * unslashable and then being able to be reallocated to another operator set. Note that unlike the allocation delay
     * which is configurable by the operator, the DEALLOCATION_DELAY is globally fixed and cannot be changed.
     */
    function DEALLOCATION_DELAY() external view returns (uint32 delay);

    /**
     * @notice Returns a list of all operator sets the operator is registered for
     * @param operator The operator address to query.
     */
    function getRegisteredSets(
        address operator
    ) external view returns (OperatorSet[] memory operatorSets);

    /**
     * @notice Returns whether the operator is registered for the operator set
     * @param operator The operator to query
     * @param operatorSet The operator set to query
     */
    function isMemberOfOperatorSet(address operator, OperatorSet memory operatorSet) external view returns (bool);

    /**
     * @notice Returns whether the operator set exists
     */
    function isOperatorSet(
        OperatorSet memory operatorSet
    ) external view returns (bool);

    /**
     * @notice Returns all the operators registered to an operator set
     * @param operatorSet The operatorSet to query.
     */
    function getMembers(
        OperatorSet memory operatorSet
    ) external view returns (address[] memory operators);

    /**
     * @notice Returns the number of operators registered to an operatorSet.
     * @param operatorSet The operatorSet to get the member count for
     */
    function getMemberCount(
        OperatorSet memory operatorSet
    ) external view returns (uint256);

    /**
     * @notice Returns the address that handles registration/deregistration for the AVS
     * If not set, defaults to the input address (`avs`)
     */
    function getAVSRegistrar(
        address avs
    ) external view returns (IAVSRegistrar);

    /**
     * @notice Returns an array of strategies in the operatorSet.
     * @param operatorSet The operatorSet to query.
     */
    function getStrategiesInOperatorSet(
        OperatorSet memory operatorSet
    ) external view returns (IStrategy[] memory strategies);

    /**
     * @notice Returns the minimum amount of stake that will be slashable as of some future block,
     * according to each operator's allocation from each strategy to the operator set. Note that this function
     * will return 0 for the slashable stake if the operator is not slashable at the time of the call.
     * @dev This method queries actual delegated stakes in the DelegationManager and applies
     * each operator's allocation to the stake to produce the slashable stake each allocation
     * represents. This method does not consider slashable stake in the withdrawal queue even though there could be
     * slashable stake in the queue.
     * @dev This minimum takes into account `futureBlock`, and will omit any pending magnitude
     * diffs that will not be in effect as of `futureBlock`. NOTE that in order to get the true
     * minimum slashable stake as of some future block, `futureBlock` MUST be greater than block.number
     * @dev NOTE that `futureBlock` should be fewer than `DEALLOCATION_DELAY` blocks in the future,
     * or the values returned from this method may not be accurate due to deallocations.
     * @param operatorSet the operator set to query
     * @param operators the list of operators whose slashable stakes will be returned
     * @param strategies the strategies that each slashable stake corresponds to
     * @param futureBlock the block at which to get allocation information. Should be a future block.
     */
    function getMinimumSlashableStake(
        OperatorSet memory operatorSet,
        address[] memory operators,
        IStrategy[] memory strategies,
        uint32 futureBlock
    ) external view returns (uint256[][] memory slashableStake);

    /**
     * @notice Returns the current allocated stake, irrespective of the operator's slashable status for the operatorSet.
     * @param operatorSet the operator set to query
     * @param operators the operators to query
     * @param strategies the strategies to query
     */
    function getAllocatedStake(
        OperatorSet memory operatorSet,
        address[] memory operators,
        IStrategy[] memory strategies
    ) external view returns (uint256[][] memory slashableStake);

    /**
     * @notice Returns whether an operator is slashable by an operator set.
     * This returns true if the operator is registered or their slashableUntil block has not passed.
     * This is because even when operators are deregistered, they still remain slashable for a period of time.
     * @param operator the operator to check slashability for
     * @param operatorSet the operator set to check slashability for
     */
    function isOperatorSlashable(address operator, OperatorSet memory operatorSet) external view returns (bool);

    /**
     * @notice Returns the address where slashed funds will be sent for a given operator set.
     * @param operatorSet The Operator Set to query.
     * @return For redistributing Operator Sets, returns the configured redistribution address set during Operator Set creation.
     *         For non-redistributing operator sets, returns the `DEFAULT_BURN_ADDRESS`.
     */
    function getRedistributionRecipient(
        OperatorSet memory operatorSet
    ) external view returns (address);

    /**
     * @notice Returns whether a given operator set supports redistribution
     * or not when funds are slashed and burned from EigenLayer.
     * @param operatorSet The Operator Set to query.
     * @return For redistributing Operator Sets, returns true.
     *         For non-redistributing Operator Sets, returns false.
     */
    function isRedistributingOperatorSet(
        OperatorSet memory operatorSet
    ) external view returns (bool);

    /**
     * @notice Returns the number of slashes for a given operator set.
     * @param operatorSet The operator set to query.
     * @return The number of slashes for the operator set.
     */
    function getSlashCount(
        OperatorSet memory operatorSet
    ) external view returns (uint256);

    /**
     * @notice Returns whether an operator is slashable by a redistributing operator set.
     * @param operator The operator to query.
     */
    function isOperatorRedistributable(
        address operator
    ) external view returns (bool);
}
"
    },
    "lib/rxp/contracts/lib/eigenlayer-contracts/src/contracts/interfaces/IKeyRegistrar.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.5.0;

import {OperatorSet} from "../libraries/OperatorSetLib.sol";
import {BN254} from "../libraries/BN254.sol";
import "./ISemVerMixin.sol";

interface IKeyRegistrarErrors {
    /// @notice Error thrown when a key is already registered
    /// @dev Error code: 0x18f78402
    /// @dev We prevent duplicate key registrations to maintain global key uniqueness and avoid conflicting operator-key mappings
    error KeyAlreadyRegistered();

    /// @notice Error thrown when an operator is already registered
    /// @dev Error code: 0x42ee68b5
    /// @dev We prevent duplicate operator registrations to prevent re-registrations with a new key
    error OperatorAlreadyRegistered();

    /// @notice Error thrown when the key format is invalid
    /// @dev Error code: 0xd1091181
    /// @dev We enforce proper key formats (20 bytes for ECDSA, valid G1/G2 points for BN254) to ensure cryptographic validity and prevent malformed key data
    error InvalidKeyFormat();

    /// @notice Error thrown when the address is zero
    /// @dev Error code: 0xd92e233d
    error ZeroAddress();

    /// @notice Error thrown when the public key is zero
    /// @dev Error code: 0x4935505f
    error ZeroPubkey();

    /// @notice Error thrown when the curve type is invalid
    /// @dev Error code: 0xfdea7c09
    /// @dev We require valid curve types (ECDSA or BN254)
    error InvalidCurveType();

    /// @notice Error thrown when the keypair is invalid
    /// @dev Error code: 0x1b56a68b
    error InvalidKeypair();

    /// @notice Error thrown when the configuration is already set
    /// @dev Error code: 0x0081f09f
    /// @dev We prevent reconfiguration of operator sets to maintain consistency and avoid conflicting curve type settings
    error ConfigurationAlreadySet();

    /// @notice Error thrown when the operator set is not configured
    /// @dev Error code: 0xb9a620da
    /// @dev We require operator sets to be configured before key operations to ensure proper curve type validation and prevent operations on unconfigured sets
    error OperatorSetNotConfigured();

    /// @notice Error thrown when the key is not found
    /// @dev Error code: 0x2e40e187
    /// @dev We require existing key registrations for deregistration operations to ensure meaningful state changes and prevent operations on non-existent keys
    error KeyNotFound(OperatorSet operatorSet, address operator);

    /// @notice Error thrown when the operator is still slashable when trying to deregister a key
    /// @dev Error code: 0x10702879
    /// @dev We prevent key deregistration while operators are slashable to avoid race conditions and ensure operators cannot escape slashing by deregistering keys
    error OperatorStillSlashable(OperatorSet operatorSet, address operator);
}

interface IKeyRegistrarTypes {
    /// @dev Enum defining supported curve types
    enum CurveType {
        NONE,
        ECDSA,
        BN254
    }

    /// @dev Structure to store key information
    struct KeyInfo {
        bool isRegistered;
        bytes keyData; // Flexible storage for different curve types
    }
}

interface IKeyRegistrarEvents is IKeyRegistrarTypes {
    /// @notice Emitted when a key is registered
    event KeyRegistered(OperatorSet operatorSet, address indexed operator, CurveType curveType, bytes pubkey);
    /// @notice Emitted when a key is deregistered
    event KeyDeregistered(OperatorSet operatorSet, address indexed operator, CurveType curveType);
    /// @notice Emitted when the aggregate BN254 key is updated
    event AggregateBN254KeyUpdated(OperatorSet operatorSet, BN254.G1Point newAggregateKey);
    /// @notice Emitted when an operator set is configured
    event OperatorSetConfigured(OperatorSet operatorSet, CurveType curveType);
}

/// @notice The `KeyRegistrar` is used by AVSs to set their key type and by operators to register and deregister keys to operatorSets
/// @notice The integration pattern is as follows:
/// 1. The AVS calls `configureOperatorSet` to set the key type for their operatorSet
/// 2. Operators call `registerKey` to register their keys to the operatorSet
/// @dev This contract requires that keys are unique across all operatorSets, globally
/// @dev For the multichain protocol, the key type of the operatorSet must be set in the `KeyRegistrar`, but the
///      AVS is not required to use the KeyRegistrar for operator key management and can implement its own registry
interface IKeyRegistrar is IKeyRegistrarErrors, IKeyRegistrarEvents, ISemVerMixin {
    /**
     * @notice Configures an operator set with curve type
     * @param operatorSet The operator set to configure
     * @param curveType Type of curve (ECDSA, BN254)
     * @dev Only authorized callers for the AVS can configure operator sets
     * @dev Reverts for:
     *      - InvalidPermissions: Caller is not authorized for the AVS (via the PermissionController)
     *      - InvalidCurveType: The curve type is not ECDSA or BN254
     *      - ConfigurationAlreadySet: The operator set is already configured
     * @dev Emits the following events:
     *      - OperatorSetConfigured: When the operator set is successfully configured with a curve type
     */
    function configureOperatorSet(OperatorSet memory operatorSet, CurveType curveType) external;

    /**
     * @notice Registers a cryptographic key for an operator with a specific operator set
     * @param operator Address of the operator to register key for
     * @param operatorSet The operator set to register the key for
     * @param pubkey Public key bytes. For ECDSA, this is the address of the key. For BN254, this is the G1 and G2 key combined (see `encodeBN254KeyData`)
     * @param signature Signature proving ownership. For ECDSA this is a signature of the `getECDSAKeyRegistrationMessageHash`. For BN254 this is a signature of the `getBN254KeyRegistrationMessageHash`.
     * @dev Can be called by operator directly or by addresses they've authorized via the `PermissionController`
     * @dev There exist no restriction on the state of the operator with respect to the operatorSet. That is, an operator
     *      does not have to be registered for the operator in the `AllocationManager` to register a key for it
     * @dev For ECDSA, we allow a smart contract to be the pubkey (via ERC1271 signatures), but note that the multichain protocol DOES NOT support smart contract signatures
     * @dev Reverts for:
     *      - InvalidPermissions: Caller is not the operator or authorized via the PermissionController
     *      - OperatorSetNotConfigured: The operator set is not configured
     *      - OperatorAlreadyRegistered: The operator is already registered for the operatorSet in the KeyRegistrar
     *      - InvalidKeyFormat: For ECDSA: The key is not exactly 20 bytes
     *      - ZeroAddress: For ECDSA: The key is the zero address
     *      - KeyAlreadyRegistered: For ECDSA: The key is already registered globally by hash
     *      - InvalidSignature: For ECDSA: The signature is not valid
     *      - InvalidKeyFormat: For BN254: The key data is not exactly 192 bytes
     *      - InvalidSignature: For BN254: The signature is not exactly 64 bytes
     *      - ZeroPubkey: For BN254: The G1 point is the zero point
     *      - InvalidSignature: For BN254: The signature is not valid
     *      - KeyAlreadyRegistered: For BN254: The key is already registered globally by hash
     * @dev Emits the following events:
     *      - KeyRegistered: When the key is successfully registered for the operator and operatorSet
     */
    function registerKey(
        address operator,
        OperatorSet memory operatorSet,
        bytes calldata pubkey,
        bytes calldata signature
    ) external;

    /**
     * @notice Deregisters a cryptographic key for an operator with a specific operator set
     * @param operator Address of the operator to deregister key for
     * @param operatorSet The operator set to deregister the key from
     * @dev Can be called by the operator directly or by addresses they've authorized via the `PermissionController`
     * @dev Keys remain in global key registry to prevent reuse
     * @dev Reverts for:
     *      - InvalidPermissions: Caller is not authorized for the operator (via the PermissionController)
     *      - OperatorStillSlashable: The operator is still slashable for the AVS
     *      - OperatorSetNotConfigured: The operator set is not configured
     *      - KeyNotFound: The operator does not have a registered key for this operator set
     * @dev Emits the following events:
     *      - KeyDeregistered: When the key is successfully deregistered for the operator and operatorSet
     */
    function deregisterKey(address operator, OperatorSet memory operatorSet) external;

    /**
     * @notice Checks if a key is registered for an operator with a specific operator set
     * @param operatorSet The operator set to check
     * @param operator Address of the operator
     * @return True if the key is registered, false otherwise
     * @dev If the operatorSet is not configured, this function will return false
     */
    function isRegistered(OperatorSet memory operatorSet, address operator) external view returns (bool);

    /**
     * @notice Gets the curve type for an operator set
     * @param operatorSet The operator set to get the curve type for
     * @return The curve type, either ECDSA, BN254, or NONE
     */
    function getOperatorSetCurveType(
        OperatorSet memory operatorSet
    ) external view returns (CurveType);

    /**
     * @notice Gets the BN254 public key for an operator with a specific operator set
     * @param operatorSet The operator set to get the key for
     * @param operator Address of the operator
     * @return g1Point The BN254 G1 public key
     * @return g2Point The BN254 G2 public key
     * @dev Reverts for:
     *      - InvalidCurveType: The operatorSet is not configured for BN254
     * @dev Returns empty points if the operator has not registered a key for the operatorSet. We
     *      recommend calling `isRegistered` first to check if the operator has a key registered
     */
    function getBN254Key(
        OperatorSet memory operatorSet,
        address operator
    ) external view returns (BN254.G1Point memory g1Point, BN254.G2Point memory g2Point);

    /**
     * @notice Gets the ECDSA public key for an operator with a specific operator set as bytes
     * @param operatorSet The operator set to get the key for
     * @param operator Address of the operator
     * @return pubkey The ECDSA public key in bytes format
     * @dev Reverts for:
     *      - InvalidCurveType: The operatorSet is not configured for ECDSA
     * @dev Returns 0x0 if the operator has not registered a key for the operatorSet. We
     *      recommend calling `isRegistered` first to check if the operator has a key registered
     */
    function getECDSAKey(OperatorSet memory operatorSet, address operator) external view returns (bytes memory);

    /**
     * @notice Gets the ECDSA public key for an operator with a specific operator set
     * @param operatorSet The operator set to get the key for
     * @param operator Address of the operator
     * @return pubkey The ECDSA public key in address format
     * @dev Reverts for:
     *      - InvalidCurveType: The operatorSet is not configured for ECDSA
     * @dev Returns 0x0 if the operator has not registered a key for the operatorSet. We
     *      recommend calling `isRegistered` first to check if the operator has a key registered
     */
    function getECDSAAddress(OperatorSet memory operatorSet, address operator) external view returns (address);

    /**
     * @notice Checks if a key hash is globally registered
     * @param keyHash Hash of the key
     * @return True if the key is globally registered
     */
    function isKeyGloballyRegistered(
        bytes32 keyHash
    ) external view returns (bool);

    /**
     * @notice Gets the key hash for an operator with a specific operator set
     * @param operatorSet The operator set to get the key hash for
     * @param operator Address of the operator
     * @return keyHash The key hash
     */
    function getKeyHash(OperatorSet memory operatorSet, address operator) external view returns (bytes32);

    /**
     * @notice Gets the operator from signing key
     * @param operatorSet The operator set to get the operator for
     * @param keyData The key data. For ECDSA, this is the signing key address. For BN254, this can be either the G1 key or the G1 and G2 key combined.
     * @return operator. Returns 0x0 if the key is not registered
     * @return status registration status. Returns false if the key is not registered
     * @dev This function decodes the key data based on the curve type of the operator set
     * @dev This function will return the operator address even if the operator is not registered for the operator set
     * @dev Reverts for:
     *      - InvalidCurveType: The CurveType is not configured
     */
    function getOperatorFromSigningKey(
        OperatorSet memory operatorSet,
        bytes memory keyData
    ) external view returns (address, bool);

    /**
     * @notice Returns the message hash for ECDSA key registration, which must be signed by the operator when registering an ECDSA key
     * @param operator The operator address
     * @param operatorSet The operator set
     * @param keyAddress The address of the key
     * @return The message hash for signing
     */
    function getECDSAKeyRegistrationMessageHash(
        address operator,
        OperatorSet memory operatorSet,
        address keyAddress
    ) external view returns (bytes32);

    /**
     * @notice Returns the message hash for BN254 key registration, which must be signed by the operator when registering a BN254 key
     * @param operator The operator address
     * @param operatorSet The operator set
     * @param keyData The BN254 key data
     * @return The message hash for signing
     */
    function getBN254KeyRegistrationMessageHash(
        address operator,
        OperatorSet memory operatorSet,
        bytes calldata keyData
    ) external view returns (bytes32);

    /**
     * @notice Encodes the BN254 key data into a bytes array
     * @param g1Point The BN254 G1 public key
     * @param g2Point The BN254 G2 public key
     * @return The encoded key data
     */
    function encodeBN254KeyData(
        BN254.G1Point memory g1Point,
        BN254.G2Point memory g2Point
    ) external pure returns (bytes memory);
}
"
    },
    "lib/rxp/contracts/lib/eigenlayer-contracts/src/contracts/interfaces/IPermissionController.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import "./ISemVerMixin.sol";

interface IPermissionControllerErrors {
    /// @notice Thrown when a non-admin caller attempts to perform an admin-only action.
    error NotAdmin();
    /// @notice Thrown when attempting to remove an admin that does not exist.
    error AdminNotSet();
    /// @notice Thrown when attempting to set an appointee for a function that already has one.
    error AppointeeAlreadySet();
    /// @notice Thrown when attempting to interact with a non-existent appointee.
    error AppointeeNotSet();
    /// @notice Thrown when attempting to remove the last remaining admin.
    error CannotHaveZeroAdmins();
    /// @notice Thrown when attempting to set an admin that is already registered.
    error AdminAlreadySet();
    /// @notice Thrown when attempting to interact with an admin that is not in pending status.
    error AdminNotPending();
    /// @notice Thrown when attempting to add an admin that is already pending.
    error AdminAlreadyPending();
}

interface IPermissionControllerEvents {
    /// @notice Emitted when an appointee is set for an account to handle specific function calls.
    event AppointeeSet(address indexed account, address indexed appointee, address target, bytes4 selector);

    /// @notice Emitted when an appointee's permission to handle function calls for an account is revoked.
    event AppointeeRemoved(address indexed account, address indexed appointee, address target, bytes4 selector);

    /// @notice Emitted when an address is set as a pending admin for an account, requiring acceptance.
    event PendingAdminAdded(address indexed account, address admin);

    /// @notice Emitted when a pending admin status is removed for an account before acceptance.
    event PendingAdminRemoved(address indexed account, address admin);

    /// @notice Emitted when an address accepts and becomes an active admin for an account.
    event AdminSet(address indexed account, address admin);

    /// @notice Emitted when an admin's permissions are removed from an account.
    event AdminRemoved(address indexed account, address admin);
}

interface IPermissionController is IPermissionControllerErrors, IPermissionControllerEvents, ISemVerMixin {
    /**
     * @notice Sets a pending admin for an account.
     * @param account The account to set the pending admin for.
     * @param admin The address to set as pending admin.
     * @dev The pending admin must accept the role before becoming an active admin.
     * @dev Multiple admins can be set for a single account.
     */
    function addPendingAdmin(address account, address admin) external;

    /**
     * @notice Removes a pending admin from an account before they have accepted the role.
     * @param account The account to remove the pending admin from.
     * @param admin The pending admin address to remove.
     * @dev Only an existing admin of the account can remove a pending admin.
     */
    function removePendingAdmin(address account, address admin) external;

    /**
     * @notice Allows a pending admin to accept their admin role for an account.
     * @param account The account to accept the admin role for.
     * @dev Only addresses that were previously set as pending admins can accept the role.
     */
    function acceptAdmin(
        address account
    ) external;

    /**
     * @notice Removes an active admin from an account.
     * @param account The account to remove the admin from.
     * @param admin The admin address to remove.
     * @dev Only an existing admin of the account can remove another admin.
     * @dev Will revert if removing this admin would leave the account with zero admins.
     */
    function removeAdmin(address account, address admin) external;

    /**
     * @notice Sets an appointee who can call specific functions on behalf of an account.
     * @param account The account to set the appointee for.
     * @param appointee The address to be given permission.
     * @param target The contract address the appointee can interact with.
     * @param selector The function selector the appointee can call.
     * @dev Only an admin of the account can set appointees.
     */
    function setAppointee(address account, address appointee, address target, bytes4 selector) external;

    /**
     * @notice Removes an appointee's permission to call a specific function.
     * @param account The account to remove the appointee from.
     * @param appointee The appointee address to remove.
     * @param target The contract address to remove permissions for.
     * @param selector The function selector to remove permissions for.
     * @dev Only an admin of the account can remove appointees.
     */
    function removeAppointee(address account, address appointee, address target, bytes4 selector) external;

    /**
     * @notice Checks if a given address is an admin of an account.
     * @param account The account to check admin status for.
     * @param caller The address to check.
     * @dev If the account has no admins, returns true only if the caller is the account itself.
     * @return Returns true if the caller is an admin, false otherwise.
     */
    function isAdmin(address account, address caller) external view returns (bool);

    /**
     * @notice Checks if an address is currently a pending admin for an account.
     * @param account The account to check pending admin status for.
     * @param pendingAdmin The address to check.
     * @return Returns true if the address is a pending admin, false otherwise.
     */
    function isPendingAdmin(address account, address pendingAdmin) external view returns (bool);

    /**
     * @notice Retrieves all active admins for an account.
     * @param account The account to get the admins for.
     * @dev If the account has no admins, returns an array containing only the account address.
     * @return An array of admin addresses.
     */
    function getAdmins(
        address account
    ) external view returns (address[] memory);

    /**
     * @notice Retrieves all pending admins for an account.
     * @param account The account to get the pending admins for.
     * @return An array of pending admin addresses.
     */
    function getPendingAdmins(
        address account
    ) external view returns (address[] memory);

    /**
     * @notice Checks if a caller has permission to call a specific function.
     * @param account The account to check permissions for.
     * @param caller The address attempting to make the call.
     * @param target The contract address being called.
     * @param selector The function selector being called.
     * @dev Returns true if the caller is either an admin or an appointed caller.
     * @dev Be mindful that upgrades to the contract may invalidate the appointee's permissions.
     * This is only possible if a function's selector changes (e.g. if a function's parameters are modified).
     * @return Returns true if the caller has permission, false otherwise.
     */
    function canCall(address account, address caller, address target, bytes4 selector) external returns (bool);

    /**
     * @notice Retrieves all permissions granted to an appointee for a given account.
     * @param account The account to check appointee permissions for.
     * @param appointee The appointee address to check.
     * @return Two arrays: target contract addresses and their corresponding function selectors.
     */
    function getAppointeePermissions(
        address account,
        address appointee
    ) external returns (address[] memory, bytes4[] memory);

    /**
     * @notice Retrieves all appointees that can call a specific function for an account.
     * @param account The account to get appointees for.
     * @param target The contract address to check.
     * @param selector The function selector to check.
     * @dev Does not include admins in the returned list, even though they have calling permission.
     * @return An array of appointee addresses.
     */
    function getAppointees(address account, address target, bytes4 selector) external returns (address[] memory);
}
"
    },
    "lib/eigenlayer-middleware/src/middlewareV2/registrar/AVSRegistrar.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol";
import {IAVSRegistrarInternal} from "../../interfaces/IAVSRegistrarInternal.sol";
import {IAllocationManager} from
    "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import {
    OperatorSetLib,
    OperatorSet
} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol";
import {IKeyRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IKeyRegistrar.sol";

import {AVSRegistrarStorage} from "./AVSRegistrarStorage.sol";

import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol";

/// @notice A minimal AVSRegistrar contract that is used to register/deregister operators for an AVS
abstract contract AVSRegistrar is Initializable, AVSRegistrarStorage {
    using OperatorSetLib for OperatorSet;

    modifier onlyAllocationManager() {
        require(msg.sender == address(allocationManager), NotAllocationManager());
        _;
    }

    constructor(
        IAllocationManager _allocationManager,
        IKeyRegistrar _keyRegistrar
    ) AVSRegistrarStorage(_allocationManager, _keyRegistrar) {
        _disableInitializers();
    }

    /// @dev This initialization function MUST be added to a child's `initialize` function to avoid uninitialized storage.
    function __AVSRegistrar_init(
        address _avs
    ) internal virtual onlyInitializing {
        avs = _avs;
    }

    /// @inheritdoc IAVSRegistrar
    /// @dev Reverts for:
    ///      - NotAllocationManager: The caller is not the allocation manager
    ///      - KeyNotRegistered: The operator has not registered a key for the given operator sets in the `KeyRegistrar`
    function registerOperator(
        address operator,
        address, /* avs */
        uint32[] calldata operatorSetIds,
        bytes calldata data
    ) external virtual onlyAllocationManager {
        _beforeRegisterOperator(operator, operatorSetIds, data);

        // Check that the operator has a valid key
        _validateOperatorKeys(operator, operatorSetIds);

        _afterRegisterOperator(operator, operatorSetIds, data);

        emit OperatorRegistered(operator, operatorSetIds);
    }

    /// @inheritdoc IAVSRegistrar
    /// @dev Reverts for:
    ///      - NotAllocationManager: The caller is not the allocation manager
    function deregisterOperator(
        address operator,
        address, /* avs */
        uint32[] calldata operatorSetIds
    ) external virtual onlyAllocationManager {
        _beforeDeregisterOperator(operator, operatorSetIds);

        _afterDeregisterOperator(operator, operatorSetIds);

        emit OperatorDeregistered(operator, operatorSetIds);
    }

    /// @inheritdoc IAVSRegistrar
    function supportsAVS(
        address _avs
    ) public view virtual returns (bool) {
        return _avs == avs;
    }

    /*
     *
     *                            INTERNAL FUNCTIONS
     *
     */

    /**
     * @notice Validates that the operator has registered a key for the given operator sets in the `KeyRegistrar`
     * @param operator The operator to validate
     * @param operatorSetIds The operator sets to validate
     * @dev Reverts for:
     *      - KeyNotRegistered: The operator has not registered a key for the given operator sets in the `KeyRegistrar`
     */
    function _validateOperatorKeys(
        address operator,
        uint32[] calldata operatorSetIds
    ) internal view {
        for (uint32 i = 0; i < operatorSetIds.length; i++) {
            OperatorSet memory operatorSet = OperatorSet({avs: avs, id: operatorSetIds[i]});
            require(keyRegistrar.isRegistered(operatorSet, operator), KeyNotRegistered());
        }
    }

    /**
     * @notice Hook called before the operator is registered
     * @param operator The operator to register
     * @param operatorSetIds The operator sets to register
     * @param data The data to register
   

Tags:
ERC20, Multisig, Swap, Upgradeable, Multi-Signature, Factory|addr:0xe9ca88618751e91e45c31d23b951bece2f55fb3d|verified:true|block:23448865|tx:0x1b421dc45361f30056bef4b3c838dbfa4757ec4b64a62e6638254a37b347b51d|first_check:1758912796

Submitted on: 2025-09-26 20:53:16

Comments

Log in to comment.

No comments yet.