EigenOperator

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": {
    "contracts/delegation/providers/eigenlayer/EigenOperator.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { IEigenOperator } from "../../../interfaces/IEigenOperator.sol";
import { IEigenServiceManager } from "../../../interfaces/IEigenServiceManager.sol";
import { EigenOperatorStorageUtils } from "../../../storage/EigenOperatorStorageUtils.sol";
import { IAllocationManager } from "./interfaces/IAllocationManager.sol";
import { IDelegationManager } from "./interfaces/IDelegationManager.sol";
import { IRewardsCoordinator } from "./interfaces/IRewardsCoordinator.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

/// @title EigenOperator
/// @author weso, Cap Labs
/// @notice This contract manages the eigen operator as proxy to disable some functionality for operators
contract EigenOperator is IEigenOperator, Initializable, EigenOperatorStorageUtils {
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    /// @inheritdoc IEigenOperator
    function initialize(address _serviceManager, address _operator, string calldata _metadata) external initializer {
        EigenOperatorStorage storage $ = getEigenOperatorStorage();
        $.serviceManager = _serviceManager;
        $.operator = _operator;
        $.totpPeriod = 28 days; // Arbitrary value

        // Fetch the eigen addresses
        IEigenServiceManager.EigenAddresses memory eigenAddresses =
            IEigenServiceManager(_serviceManager).eigenAddresses();
        $.allocationManager = eigenAddresses.allocationManager;
        $.delegationManager = eigenAddresses.delegationManager;
        $.rewardsCoordinator = eigenAddresses.rewardsCoordinator;

        // Register as an operator on delegation manager
        IDelegationManager($.delegationManager).registerAsOperator(address(this), 0, _metadata);
    }

    /// @inheritdoc IEigenOperator
    function registerOperatorSetToServiceManager(uint32 _operatorSetId, address _staker) external {
        EigenOperatorStorage storage $ = getEigenOperatorStorage();
        if (msg.sender != $.serviceManager) revert NotServiceManager();
        if ($.restaker != address(0)) revert AlreadyRegistered();
        if (_staker == address(0)) revert ZeroAddress();

        /// @dev The digest is calculated using the staker and operator addresses
        bytes32 digest = calculateTotpDigestHash(_staker, address(this));
        /// @dev Allowlist the digest for delegation approval from the staker
        $.allowlistedDigests[digest] = true;
        $.restaker = _staker;

        // Build the register params
        uint32[] memory operatorSetIds = new uint32[](1);
        operatorSetIds[0] = _operatorSetId;

        IAllocationManager.RegisterParams memory params =
            IAllocationManager.RegisterParams({ avs: msg.sender, operatorSetIds: operatorSetIds, data: "" });

        // 1. Register the operator set to the service manager, which in turn calls RegisterOperator on the Eigen Service Manager
        IAllocationManager($.allocationManager).registerForOperatorSets(address(this), params);

        // 2. Set the operator split to 0, all rewards go to restakers
        IRewardsCoordinator($.rewardsCoordinator).setOperatorAVSSplit(address(this), msg.sender, 0);
    }

    /// @inheritdoc IEigenOperator
    function allocate(uint32 _operatorSetId, address _strategy) external {
        EigenOperatorStorage storage $ = getEigenOperatorStorage();
        if (msg.sender != $.serviceManager) revert NotServiceManager();

        (, IAllocationManager.Allocation[] memory _allocations) =
            IAllocationManager($.allocationManager).getStrategyAllocations(address(this), _strategy);
        if (_allocations.length != 0) revert AlreadyAllocated();

        // The strategy that the restakers capital is deployed to
        address[] memory strategies = new address[](1);
        strategies[0] = _strategy;

        // Only 1 allocation so 1e18 just means everything will be allocated to the avs
        uint64[] memory magnitudes = new uint64[](1);
        magnitudes[0] = 1e18;

        // Create the allocation params
        IAllocationManager.OperatorSet memory operatorSet =
            IAllocationManager.OperatorSet({ avs: msg.sender, id: _operatorSetId });
        IAllocationManager.AllocateParams[] memory allocations = new IAllocationManager.AllocateParams[](1);
        allocations[0] = IAllocationManager.AllocateParams({
            operatorSet: operatorSet,
            strategies: strategies,
            newMagnitudes: magnitudes
        });

        // Allocates the operator set. Can only be called after ALLOCATION_CONFIGURATION_DELAY (approximately 17.5 days) has passed since registration.
        IAllocationManager($.allocationManager).modifyAllocations(address(this), allocations);
    }

    /// @inheritdoc IEigenOperator
    function updateOperatorMetadataURI(string calldata _metadataURI) external {
        EigenOperatorStorage storage $ = getEigenOperatorStorage();
        if (msg.sender != $.operator) revert NotOperator();
        IDelegationManager($.delegationManager).updateOperatorMetadataURI(address(this), _metadataURI);
    }

    /// @inheritdoc IEigenOperator
    function advanceTotp() external {
        EigenOperatorStorage storage $ = getEigenOperatorStorage();
        if (msg.sender != $.restaker) revert NotRestaker();

        // If for some reason the delegation approval has expired, allowlist the new digest
        // This shouldn't matter since only the restaker can call this function
        bytes32 digest = calculateTotpDigestHash($.restaker, address(this));
        $.allowlistedDigests[digest] = true;
    }

    /// @inheritdoc IEigenOperator
    function eigenServiceManager() external view returns (address) {
        return getEigenOperatorStorage().serviceManager;
    }

    /// @inheritdoc IEigenOperator
    function operator() external view returns (address) {
        return getEigenOperatorStorage().operator;
    }

    /// @inheritdoc IEigenOperator
    function restaker() external view returns (address) {
        return getEigenOperatorStorage().restaker;
    }

    /// @inheritdoc IEigenOperator
    function isValidSignature(bytes32 _digest, bytes memory) external view override returns (bytes4 magicValue) {
        EigenOperatorStorage storage $ = getEigenOperatorStorage();

        /// If the created at epoch is > the current epoch, the operator is not allowed to delegate
        uint32 createdAtEpoch = IEigenServiceManager($.serviceManager).createdAtEpoch($.operator);
        uint256 calcIntervalSeconds = IEigenServiceManager($.serviceManager).calculationIntervalSeconds();
        uint32 currentEpoch = uint32(block.timestamp / calcIntervalSeconds);

        if (createdAtEpoch > currentEpoch) return bytes4(0xffffffff);

        // This gets called by the delegation manager to check if the operator is allowed to delegate
        if ($.allowlistedDigests[_digest]) {
            return bytes4(0x1626ba7e); // ERC1271 magic value for valid signatures
        } else {
            return bytes4(0xffffffff);
        }
    }

    /// @inheritdoc IEigenOperator
    function getCurrentTotpExpiryTimestamp() public view returns (uint256) {
        EigenOperatorStorage storage $ = getEigenOperatorStorage();
        uint256 current = block.timestamp / $.totpPeriod;
        return (current + 1) * $.totpPeriod; // End of the current period
    }

    /// @inheritdoc IEigenOperator
    function currentTotp() public view returns (uint256) {
        EigenOperatorStorage storage $ = getEigenOperatorStorage();
        return block.timestamp / $.totpPeriod;
    }

    /// @inheritdoc IEigenOperator
    function calculateTotpDigestHash(address _staker, address _operator) public view returns (bytes32) {
        uint256 expiryTimestamp = getCurrentTotpExpiryTimestamp();
        return IDelegationManager(getEigenOperatorStorage().delegationManager).calculateDelegationApprovalDigestHash(
            _staker, _operator, address(this), bytes32(uint256(expiryTimestamp)), expiryTimestamp
        );
    }
}
"
    },
    "contracts/interfaces/IEigenOperator.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

interface IEigenOperator {
    /// @dev Error thrown when the caller is not the service manager
    error NotServiceManager();
    /// @dev Error thrown when the caller is not the operator
    error NotOperator();
    /// @dev Error thrown when the operator is already allocated to a strategy
    error AlreadyAllocated();
    /// @dev Error thrown when the caller is not the restaker
    error NotRestaker();
    /// @dev Error thrown when the operator is already registered
    error AlreadyRegistered();
    /// @dev Error thrown when the staker is the zero address
    error ZeroAddress();

    /// @dev EigenOperator storage
    /// @param serviceManager EigenServiceManager address
    /// @param operator Eigen operator address
    /// @param allocationManager EigenCloud Allocation manager address
    /// @param delegationManager EigenCloud Delegation manager address
    /// @param rewardsCoordinator EigenCloud Rewards coordinator address
    struct EigenOperatorStorage {
        address serviceManager;
        address operator;
        address allocationManager;
        address delegationManager;
        address rewardsCoordinator;
        address restaker;
        uint32 totpPeriod;
        mapping(bytes32 => bool) allowlistedDigests;
    }

    /// @notice Initialize the EigenOperator
    /// @param _serviceManager EigenServiceManager address
    /// @param _operator Eigen operator address
    /// @param _metadata Metadata URI
    function initialize(address _serviceManager, address _operator, string calldata _metadata) external;

    /// @notice Register an operator set to the service manager
    /// @param _operatorSetId Operator set id
    function registerOperatorSetToServiceManager(uint32 _operatorSetId, address _staker) external;

    /// @notice Update the operator metadata URI
    /// @param _metadataURI The new metadata URI
    function updateOperatorMetadataURI(string calldata _metadataURI) external;

    /// @notice Allocate the operator set to the strategy, called by service manager.
    /// @param _operatorSetId Operator set id
    /// @param _strategy Strategy address
    function allocate(uint32 _operatorSetId, address _strategy) external;

    /// @notice Advance the TOTP
    function advanceTotp() external;

    /// @notice Get the service manager
    /// @return The service manager address
    function eigenServiceManager() external view returns (address);

    /**
     * @notice Implements the IERC1271 interface to validate signatures
     * @dev In this implementation, we check if the digest hash is directly allowlisted
     * @param digest The digest hash containing encoded delegation information
     * @return magicValue Returns the ERC1271 magic value if valid, or 0xffffffff if invalid
     */
    function isValidSignature(bytes32 digest, bytes memory signature) external view returns (bytes4 magicValue);

    /// @notice Get the operator
    /// @return The operator or borrower address in the cap system
    function operator() external view returns (address);

    /// @notice Get the current TOTP
    /// @return The current TOTP
    function currentTotp() external view returns (uint256);

    /// @notice Get the current TOTP expiry timestamp
    /// @return The current TOTP expiry timestamp
    function getCurrentTotpExpiryTimestamp() external view returns (uint256);

    /// @notice Calculate the TOTP digest hash
    /// @param _staker The staker address
    /// @param _operator The operator address
    /// @return The TOTP digest hash
    function calculateTotpDigestHash(address _staker, address _operator) external view returns (bytes32);

    /// @notice Get the restaker
    /// @return The restaker address
    function restaker() external view returns (address);
}
"
    },
    "contracts/interfaces/IEigenServiceManager.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

import { UpgradeableBeacon } from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import { IRewardsCoordinator } from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol";

interface IEigenServiceManager {
    /// @dev Invalid AVS
    error InvalidAVS();
    /// @dev Invalid operator set ids
    error InvalidOperatorSetIds();
    /// @dev Invalid operator
    error InvalidOperator();
    /// @dev Operator already registered
    error AlreadyRegisteredOperator();
    /// @dev Invalid redistribution recipient
    error InvalidRedistributionRecipient();
    /// @dev Zero address
    error ZeroAddress();
    /// @dev Operator set already created
    error OperatorSetAlreadyCreated();
    /// @dev Operator doesn't exist
    error OperatorDoesntExist();
    /// @dev Min magnitude not met
    error MinMagnitudeNotMet();
    /// @dev Invalid decimals
    error InvalidDecimals();
    /// @dev Min share not met
    error MinShareNotMet();
    /// @dev Zero slash
    error ZeroSlash();
    /// @dev Slash share too small
    error SlashShareTooSmall();

    /// @dev Operator registered
    event OperatorRegistered(
        address indexed operator, address indexed eigenOperator, address indexed avs, uint32 operatorSetId
    );
    /// @dev Emitted on slash
    event Slash(address indexed agent, address indexed recipient, uint256 slashShare, uint48 timestamp);
    /// @dev Strategy registered
    event StrategyRegistered(address indexed strategy, address indexed operator);
    /// @dev Epochs between distributions set
    event EpochsBetweenDistributionsSet(uint32 epochsBetweenDistributions);
    /// @dev Min reward amount set
    event MinRewardAmountSet(uint256 minRewardAmount);
    /// @dev Distributed rewards
    event DistributedRewards(address indexed strategy, address indexed token, uint256 amount);

    /// @dev EigenServiceManager storage
    /// @param eigen Eigen addresses
    /// @param oracle Oracle address
    /// @param eigenOperatorInstance Eigen operator instance
    /// @param epochsBetweenDistributions Epochs between distributions
    /// @param nextOperatorId Next operator id
    /// @param pendingRewards Pending rewards
    /// @param eigenOperatorToOperator Mapping from eigen operator to operator
    struct EigenServiceManagerStorage {
        EigenAddresses eigen;
        address oracle;
        address eigenOperatorInstance;
        address[] redistributionRecipients;
        uint32 epochsBetweenDistributions;
        uint32 nextOperatorId;
        mapping(address => uint256) pendingRewardsByToken;
        mapping(address => CachedOperatorData) operators;
        mapping(address => address) eigenOperatorToOperator;
    }

    /// @dev Cached operator data
    /// @param eigenOperator Eigen operator address
    /// @param strategy Strategy address
    /// @param createdAtEpoch Epoch at which the operator was created
    /// @param operatorSetId Operator set id
    /// @param pendingRewards Pending rewards
    struct CachedOperatorData {
        address eigenOperator;
        address strategy;
        uint32 createdAtEpoch;
        uint32 operatorSetId;
        mapping(address => uint256) pendingRewards;
        mapping(address => uint32) lastDistributionEpoch;
    }

    /// @dev Eigen addresses
    /// @param allocationManager Allocation manager address
    /// @param delegationManager Delegation manager address
    /// @param strategyManager Strategy manager address
    /// @param rewardsCoordinator Rewards coordinator address
    struct EigenAddresses {
        address allocationManager;
        address delegationManager;
        address strategyManager;
        address rewardsCoordinator;
    }

    /// @notice Initialize the EigenServiceManager
    /// @param _accessControl Access control contract
    /// @param _addresses Eigen addresses
    /// @param _oracle Oracle contract
    /// @param _rewardDuration Reward duration
    function initialize(
        address _accessControl,
        EigenAddresses memory _addresses,
        address _oracle,
        uint32 _rewardDuration
    ) external;

    /**
     * @notice Creates a new rewards submission to the EigenLayer RewardsCoordinator contract, to be split amongst the
     * set of stakers delegated to operators who are registered to this `avs`
     * @param rewardsSubmissions The rewards submissions being created
     * @dev Only callable by the permissioned rewardsInitiator address
     * @dev The duration of the `rewardsSubmission` cannot exceed `MAX_REWARDS_DURATION`
     * @dev The tokens are sent to the `RewardsCoordinator` contract
     * @dev Strategies must be in ascending order of addresses to check for duplicates
     * @dev This function will revert if the `rewardsSubmission` is malformed,
     * e.g. if the `strategies` and `weights` arrays are of non-equal lengths
     * @dev This function may fail to execute with a large number of submissions due to gas limits. Use a
     * smaller array of submissions if necessary.
     */

    /**
     * @notice Distributes rewards to the operator
     * @param _operator The operator to distribute rewards to
     * @param _token The token to distribute rewards for
     */
    function distributeRewards(address _operator, address _token) external;

    /**
     * @notice Returns the coverage for an operator
     * @param operator The operator to get the coverage for
     * @return The coverage of the operator
     */
    function coverage(address operator) external view returns (uint256);

    /**
     * @notice Registers an operator to the AVS, called by the Allocation Manager contract (access control set for the allocation manager).
     * @param _operator The operator to register
     * @param _avs The AVS to register the operator to
     * @param _operatorSetIds The operator set ids to register the operator to
     * @param _data Additional data
     */
    function registerOperator(address _operator, address _avs, uint32[] calldata _operatorSetIds, bytes calldata _data)
        external;

    /**
     * @notice Registers a strategy to the AVS
     * @param _strategy The strategy to register
     * @param _operator The operator to register the strategy to
     * @param _restaker The restaker to register the strategy to
     * @param _operatorMetadata The metadata for the operator
     * @return _operatorSetId The operator set id
     */
    function registerStrategy(address _strategy, address _operator, address _restaker, string memory _operatorMetadata)
        external
        returns (uint32 _operatorSetId);

    /**
     * @notice Slashes an operator
     * @param _operator The operator to slash
     * @param _recipient The recipient of the slashed collateral
     * @param _slashShare The share of the slashable collateral to slash
     * @param _timestamp The timestamp of the slash (unused for eigenlayer)
     */
    function slash(address _operator, address _recipient, uint256 _slashShare, uint48 _timestamp) external;

    /**
     * @notice Allocates the operator set, is public and can be called permissionless. We would have allocated on registerStrategy but it needs to wait at least a block.
     * @param _operator Operator address
     */
    function allocate(address _operator) external;

    /**
     * @notice Returns the slashable collateral for an operator
     * @param operator The operator to get the slashable collateral for
     * @param timestamp The timestamp to get the slashable collateral for (unused for eigenlayer)
     * @return The slashable collateral of the operator
     */
    function slashableCollateral(address operator, uint48 timestamp) external view returns (uint256);

    /**
     * @notice Sets the epochs between distributions
     * @param _epochsBetweenDistributions The epochs between distributions
     */
    function setEpochsBetweenDistributions(uint32 _epochsBetweenDistributions) external;

    /**
     * @notice Updates the AVS metadata URI
     * @param _metadataURI The new metadata URI
     */
    function updateAVSMetadataURI(string calldata _metadataURI) external;

    /**
     * @notice Upgrades the eigen operator implementation
     * @param _newImplementation The new implementation
     */
    function upgradeEigenOperatorImplementation(address _newImplementation) external;

    /**
     * @notice Returns the eigen addresses
     * @return The eigen addresses
     */
    function eigenAddresses() external view returns (EigenAddresses memory);

    /**
     * @notice Returns the operator to strategy mapping
     * @return The operator to strategy mapping
     */
    function operatorToStrategy(address operator) external view returns (address);

    /**
     * @notice Returns the operator set id for an operator
     * @param operator The operator to get the operator set id for
     * @return The operator set id of the operator
     */
    function operatorSetId(address operator) external view returns (uint32);

    /**
     * @notice Returns the epochs between distributions
     * @return The epochs between distributions
     */
    function epochsBetweenDistributions() external view returns (uint32);

    /**
     * @notice Returns the created at epoch for an operator
     * @param operator The operator to get the created at epoch for
     * @return The created at epoch of the operator
     */
    function createdAtEpoch(address operator) external view returns (uint32);

    /**
     * @notice Returns the calculation interval seconds
     * @return The calculation interval seconds
     */
    function calculationIntervalSeconds() external view returns (uint256);

    /**
     * @notice Returns the pending rewards for an operator
     * @param _strategy The strategy to get the pending rewards for
     * @param _token The token to get the pending rewards for
     * @return The pending rewards of the strategy
     */
    function pendingRewards(address _strategy, address _token) external view returns (uint256);

    /**
     * @notice Returns the eigen operator for an operator
     * @param _operator The operator to get the eigen operator for
     * @return The eigen operator of the operator
     */
    function getEigenOperator(address _operator) external view returns (address);
}
"
    },
    "contracts/storage/EigenOperatorStorageUtils.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

import { IEigenOperator } from "../interfaces/IEigenOperator.sol";

/// @title EigenOperator Storage Utils
/// @author weso, Cap Labs
/// @notice Storage utilities for EigenOperator
abstract contract EigenOperatorStorageUtils {
    /// @dev keccak256(abi.encode(uint256(keccak256("cap.storage.EigenOperator")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant EigenOperatorStorageLocation =
        0x960b4b43d7da1001f900c7ba4e78a0a350e1c730ee58306f13b7c137edf1ee00;

    /// @dev Get EigenOperator storage
    /// @return $ Storage pointer
    function getEigenOperatorStorage() internal pure returns (IEigenOperator.EigenOperatorStorage storage $) {
        assembly {
            $.slot := EigenOperatorStorageLocation
        }
    }
}
"
    },
    "contracts/delegation/providers/eigenlayer/interfaces/IAllocationManager.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

interface IAllocationManager {
    /**
     * @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;
        address[] strategies;
        uint256[] wadsToSlash;
        string description;
    }

    /**
     * @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;
        address[] strategies;
    }

    /**
     * @notice An operator set identified by the AVS address and an identifier
     * @param avs The address of the AVS this operator set belongs to
     * @param id The unique identifier for the operator set
     */
    struct OperatorSet {
        address avs;
        uint32 id;
    }

    /**
     * @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 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 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,
        address[] memory strategies,
        uint32 futureBlock
    ) external view returns (uint256[][] memory slashableStake);

    /**
     * @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 Adds strategies to an operator set.
     * @param avs The AVS address initiating the addition.
     * @param operatorSetId The ID of the operator set to which strategies are being added.
     * @param strategies The strategies to add to the operator set.
     */
    function addStrategiesToOperatorSet(address avs, uint32 operatorSetId, address[] calldata strategies) external;

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

    /**
     * @notice Returns the maximum magnitude of a given operator and strategy.
     * @param operator The operator address.
     * @param strategy The strategy address.
     * @return The maximum magnitude of the operator and strategy.
     */
    function getMaxMagnitude(address operator, address strategy) external view returns (uint64);

    /**
     * @notice Returns the allocatable magnitude of a given operator and strategy.
     * @param operator The operator address.
     * @param strategy The strategy address.
     * @return The allocatable magnitude of the operator and strategy.
     */
    function getAllocatableMagnitude(address operator, address strategy) external view returns (uint64);

    /**
     * @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 Allows an operator to register for an operator set.
     * @param operator The operator address.
     * @param params The register parameters, containing:
     *  - avs: The AVS being registered for.
     *  - operatorSetIds: The operator sets within the AVS to register for.
     *  - data: Extra data to be passed to the AVS to complete registration.
     */
    function registerForOperatorSets(address operator, RegisterParams calldata params) external;

    /**
     * @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;
        address[] strategies;
        uint64[] newMagnitudes;
    }

    /**
     * @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 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 Returns the allocation information from a strategy to an operator set, for an operator
     * @param operator the operator to get the allocation information for
     * @param strategy the strategy to get the allocation information for
     * @return operatorSet the operator set to which the strategy is allocated
     * @return allocation the allocation information
     */
    function getStrategyAllocations(address operator, address strategy)
        external
        view
        returns (OperatorSet[] memory, Allocation[] memory);
}
"
    },
    "contracts/delegation/providers/eigenlayer/interfaces/IDelegationManager.sol": {
      "content": "    // SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

interface IDelegationManager {
    /// @notice Struct that bundles together a signature and an expiration time for the signature.
    /// @dev Used primarily for stack management.
    struct SignatureWithExpiry {
        // the signature itself, formatted as a single bytes object
        bytes signature;
        // the expiration timestamp (UTC) of the signature
        uint256 expiry;
    }

    /**
     * @param strategies The strategies to withdraw from
     * @param depositShares For each strategy, the number of deposit shares to withdraw. Deposit shares can
     * be queried via `getDepositedShares`.
     * NOTE: The number of shares ultimately received when a withdrawal is completed may be lower depositShares
     * if the staker or their delegated operator has experienced slashing.
     * @param __deprecated_withdrawer This field is ignored. The only party that may complete a withdrawal
     * is the staker that originally queued it. Alternate withdrawers are not supported.
     */
    struct QueuedWithdrawalParams {
        address[] strategies;
        uint256[] depositShares;
        address __deprecated_withdrawer;
    }

    /**
     * @dev A struct representing an existing queued withdrawal. After the withdrawal delay has elapsed, this withdrawal can be completed via `completeQueuedWithdrawal`.
     * A `Withdrawal` is created by the `DelegationManager` when `queueWithdrawals` is called. The `withdrawalRoots` hashes returned by `queueWithdrawals` can be used
     * to fetch the corresponding `Withdrawal` from storage (via `getQueuedWithdrawal`).
     *
     * @param staker The address that queued the withdrawal
     * @param delegatedTo The address that the staker was delegated to at the time the withdrawal was queued. Used to determine if additional slashing occurred before
     * this withdrawal became completable.
     * @param withdrawer The address that will call the contract to complete the withdrawal. Note that this will always equal `staker`; alternate withdrawers are not
     * supported at this time.
     * @param nonce The staker's `cumulativeWithdrawalsQueued` at time of queuing. Used to ensure withdrawals have unique hashes.
     * @param startBlock The block number when the withdrawal was queued.
     * @param strategies The strategies requested for withdrawal when the withdrawal was queued
     * @param scaledShares The staker's deposit shares requested for withdrawal, scaled by the staker's `depositScalingFactor`. Upon completion, these will be
     * scaled by the appropriate slashing factor as of the withdrawal's completable block. The result is what is actually withdrawable.
     */
    struct Withdrawal {
        address staker;
        address delegatedTo;
        address withdrawer;
        uint256 nonce;
        uint32 startBlock;
        address[] strategies;
        uint256[] scaledShares;
    }

    /// @notice Get the slashable shares in queue for a given operator and strategy
    /// @param operator The operator address
    /// @param strategy The strategy address
    /// @return The slashable shares in queue
    function getSlashableSharesInQueue(address operator, address strategy) external view returns (uint256);

    /// @notice Get the operator shares for a given operator and strategies
    /// @param operator The operator address
    /// @param strategies The strategies
    /// @return The operator shares
    function getOperatorShares(address operator, address[] memory strategies)
        external
        view
        returns (uint256[] memory);

    /**
     * @notice Returns the number of shares in storage for a staker and all their strategies
     */
    function getDepositedShares(address staker) external view returns (address[] memory, uint256[] memory);

    function queueWithdrawals(QueuedWithdrawalParams[] calldata params)
        external
        returns (bytes32[] memory withdrawalRoots);

    /**
     * @notice Used to complete a queued withdrawal
     * @param withdrawal The withdrawal to complete
     * @param tokens Array in which the i-th entry specifies the `token` input to the 'withdraw' function of the i-th Strategy in the `withdrawal.strategies` array.
     * @param tokens For each `withdrawal.strategies`, the underlying token of the strategy
     * NOTE: if `receiveAsTokens` is false, the `tokens` array is unused and can be filled with default values. However, `tokens.length` MUST still be equal to `withdrawal.strategies.length`.
     * NOTE: For the `beaconChainETHStrategy`, the corresponding `tokens` value is ignored (can be 0).
     * @param receiveAsTokens If true, withdrawn shares will be converted to tokens and sent to the caller. If false, the caller receives shares that can be delegated to an operator.
     * NOTE: if the caller receives shares and is currently delegated to an operator, the received shares are
     * automatically delegated to the caller's current operator.
     */
    function completeQueuedWithdrawal(Withdrawal calldata withdrawal, address[] calldata tokens, bool receiveAsTokens)
        external;

    /**
     * @notice Caller delegates their stake to an operator.
     * @param operator The account (`msg.sender`) is delegating its assets to for use in serving applications built on EigenLayer.
     * @param approverSignatureAndExpiry (optional) Verifies the operator approves of this delegation
     * @param approverSalt (optional) A unique single use value tied to an individual signature.
     * @dev The signature/salt are used ONLY if the operator has configured a delegationApprover.
     * If they have not, these params can be left empty.
     */
    function delegateTo(address operator, SignatureWithExpiry memory approverSignatureAndExpiry, bytes32 approverSalt)
        external;

    /**
     * @notice Undelegates the staker from their operator and queues a withdrawal for all of their shares
     * @param staker The account to be undelegated
     * @return withdrawalRoots The roots of the newly queued withdrawals, if a withdrawal was queued. Returns
     * an empty array if none was queued.
     *
     * @dev Reverts if the `staker` is also an operator, since operators are not allowed to undelegate from themselves.
     * @dev Reverts if the caller is not the staker, nor the operator who the staker is delegated to, nor the operator's specified "delegationApprover"
     * @dev Reverts if the `staker` is not delegated to an operator
     */
    function undelegate(address staker) external returns (bytes32[] memory withdrawalRoots);

    /**
     * @notice Register as an operator
     * @param initDelegationApprover The initial delegation approver
     * @param allocationDelay The allocation delay
     * @param metadataURI The metadata URI
     */
    function registerAsOperator(address initDelegationApprover, uint32 allocationDelay, string calldata metadataURI)
        external;

    function isOperator(address operator) external view returns (bool);

    function isDelegated(address staker) external view returns (bool);

    function delegationApprover(address operator) external view returns (address);

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

    function calculateDelegationApprovalDigestHash(
        address staker,
        address operator,
        address approver,
        bytes32 approverSalt,
        uint256 expiry
    ) external view returns (bytes32);
}
"
    },
    "contracts/delegation/providers/eigenlayer/interfaces/IRewardsCoordinator.sol": {
      "content": "    // SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

interface IRewardsCoordinator {
    /**
     * @notice An operator set identified by the AVS address and an identifier
     * @param avs The address of the AVS this operator set belongs to
     * @param id The unique identifier for the operator set
     */
    struct OperatorSet {
        address avs;
        uint32 id;
    }

    /**
     * @notice A linear combination of strategies and multipliers for AVSs to weigh
     * EigenLayer strategies.
     * @param strategy The EigenLayer strategy to be used for the rewards submission
     * @param multiplier The weight of the strategy in the rewards submission
     */
    struct StrategyAndMultiplier {
        address strategy;
        uint96 multiplier;
    }

    /**
     * Sliding Window for valid RewardsSubmission startTimestamp
     *
     * Scenario A: GENESIS_REWARDS_TIMESTAMP IS WITHIN RANGE
     *         <-----MAX_RETROACTIVE_LENGTH-----> t (block.timestamp) <---MAX_FUTURE_LENGTH--->
     *             <--------------------valid range for startTimestamp------------------------>
     *             ^
     *         GENESIS_REWARDS_TIMESTAMP
     *
     *
     * Scenario B: GENESIS_REWARDS_TIMESTAMP IS OUT OF RANGE
     *         <-----MAX_RETROACTIVE_LENGTH-----> t (block.timestamp) <---MAX_FUTURE_LENGTH--->
     *         <------------------------valid range for startTimestamp------------------------>
     *     ^
     * GENESIS_REWARDS_TIMESTAMP
     * @notice RewardsSubmission struct submitted by AVSs when making rewards for their operators and stakers
     * RewardsSubmission can be for a time range within the valid window for startTimestamp and must be within max duration.
     * See `createAVSRewardsSubmission()` for more details.
     * @param strategiesAndMultipliers The strategies and their relative weights
     * cannot have duplicate strategies and need to be sorted in ascending address order
     * @param token The rewards token to be distributed
     * @param amount The total amount of tokens to be distributed
     * @param startTimestamp The timestamp (seconds) at which the submission range is considered for distribution
     * could start in the past or in the future but within a valid range. See the diagram above.
     * @param duration The duration of the submission range in seconds. Must be <= MAX_REWARDS_DURATION
     */
    struct RewardsSubmission {
        StrategyAndMultiplier[] strategiesAndMultipliers;
        address token;
        uint256 amount;
        uint32 startTimestamp;
        uint32 duration;
    }

    /**
     * @notice Creates a new rewards submission on behalf of an AVS, to be split amongst the
     * set of stakers delegated to operators who are registered to the `avs`
     * @param rewardsSubmissions The rewards submissions being created
     * @dev Expected to be called by the ServiceManager of the AVS on behalf of which the submission is being made
     * @dev The duration of the `rewardsSubmission` cannot exceed `MAX_REWARDS_DURATION`
     * @dev The duration of the `rewardsSubmission` cannot be 0 and must be a multiple of `CALCULATION_INTERVAL_SECONDS`
     * @dev The tokens are sent to the `RewardsCoordinator` contract
     * @dev Strategies must be in ascending order of addresses to check for duplicates
     * @dev This function will revert if the `rewardsSubmission` is malformed,
     * e.g. if the `strategies` and `weights` arrays are of non-equal lengths
     */
    function createAVSRewardsSubmission(RewardsSubmission[] calldata rewardsSubmissions) external;

    /**
     * @notice Sets the split for a specific operator for a specific avs
     * @param operator The operator who is setting the split
     * @param avs The avs for which the split is being set by the operator
     * @param split The split for the operator for the specific avs in bips.
     * @dev Only callable by the operator
     * @dev Split has to be between 0 and 10000 bips (inclusive)
     * @dev The split will be activated after the activation delay
     */
    function setOperatorAVSSplit(address operator, address avs, uint16 split) external;

    function CALCULATION_INTERVAL_SECONDS() external pure returns (uint256);

    /**
     * @notice A reward struct for an operator
     * @param operator The operator to be rewarded
     * @param amount The reward amount for the operator
     */
    struct OperatorReward {
        address operator;
        uint256 amount;
    }

    /**
     * @notice OperatorDirectedRewardsSubmission struct submitted by AVSs when making operator-directed rewards for their operators and stakers.
     * @param strategiesAndMultipliers The strategies and their relative weights.
     * @param token The rewards token to be distributed.
     * @param operatorRewards The rewards for the operators.
     * @param startTimestamp The timestamp (seconds) at which the submission range is considered for distribution.
     * @param duration The duration of the submission range in seconds.
     * @param description Describes what the rewards submission is for.
     */
    struct OperatorDirectedRewardsSubmission {
        StrategyAndMultiplier[] strategiesAndMultipliers;
        address token;
        OperatorReward[] operatorRewards;
        uint32 startTimestamp;
        uint32 duration;
        string description;
    }

    function createOperatorDirectedOperatorSetRewardsSubmission(
        OperatorSet calldata operatorSet,
        OperatorDirectedRewardsSubmission[] calldata operatorDirectedRewardsSubmissions
    ) external;

    function MAX_REWARDS_DURATION() external pure returns (uint32);

    function activationDelay() external pure returns (uint256);
}
"
    },
    "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reinitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.
     *
     * NOTE: Consider following the ERC-7201 formula to derive storage locations.
     */
    function _initializableStorageSlot() internal pure virtual returns (bytes32) {
        return INITIALIZABLE_STORAGE;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        bytes32 slot = _initializableStorageSlot();
        assembly {
            $.slot := slot
        }
    }
}
"
    },
    "node_modules/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/UpgradeableBeacon.sol)

pragma solidity ^0.8.20;

import {IBeacon} from "./IBeacon.sol";
import {Ownable} from "../../access/Ownable.sol";

/**
 * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their
 * implementation contract, which is where they will delegate all function calls.
 *
 * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.
 */
contract UpgradeableBeacon is IBeacon, Ownable {
    address private _implementation;

    /**
     * @dev The `implementation` of the beacon is invalid.
     */
    error BeaconInvalidImplementation(address implementation);

    /**
     * @dev Emitted when the implementation returned by the beacon is changed.
     */
    event Upgraded(address indexed implementation);

    /**
     * @dev Sets the address of the initial implementation, and the initial owner who can upgrade the beacon.
     */
    constructor(address implementation_, address initialOwner) Ownable(initialOwner) {
        _setImplementation(implementation_);
    }

    /**
     * @dev Returns the current implementation address.
     */
    function implementation() public view virtual returns (address) {
        return _implementation;
    }

    /**
     * @dev Upgrades the beacon to a new implementation.
     *
     * Emits an {Upgraded} event.
     *
     * Requirements:
     *
     * - msg.sender must be the owner of the contract.
     * - `newImplementation` must be a contract.
     */
    function upgradeTo(address newImplementation) public virtual onlyOwner {
        _setImplementation(newImplementation);
    }

    /**
     * @dev Sets the implementation contract address for this beacon
     *
     * Requirements:
     *
     * - `newImplementation` must be a contract.
     */
    function _setImplementation(address newImplementation) private {
        if (newImplementation.code.length == 0) {
            revert BeaconInvalidImplementation(newImplementation);
        }
        _implementation = newImplementation;
        emit Upgraded(newImplementation);
    }
}
"
    },
    "node_modules/eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.12;

import "openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IStrategy.sol";

/**
 * @title Interface for the `IRewardsCoordinator` contract.
 * @author Layr Labs, Inc.
 * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service
 * @notice Allows AVSs to make "Rewards Submissions", which get distributed amongst the AVSs' confirmed
 * Operators and the Stakers delegated to those Operators.
 * Calculations are performed based on the completed RewardsSubmission, with the results posted in
 * a Merkle root against which Stakers & Operators can make claims.
 */
interface IRewardsCoordinator {
    /// STRUCTS ///
    /**
     * @notice A linear combination of strategies and multipliers for AVSs to weigh
     * EigenLayer strategies.
     * @param strategy The EigenLayer strategy to be used for the rewards submission
     * @param multiplier The weight of the strategy in the rewards submission
     */
    struct StrategyAndMultiplier {
        IStrategy strategy;
        uint96 multiplier;
    }

    /**
     * Sliding Window for valid RewardsSubmission startTimestamp
     *
     * Scenario A: GENESIS_REWARDS_TIMESTAMP IS WITHIN RANGE
     *         <-----MAX_RETROACTIVE_LENGTH-----> t (block.timestamp) <---MAX_FUTURE_LENGTH--->
     *             <--------------------valid range for startTimestamp------------------------>
     *             ^
     *         GENESIS_REWARDS_TIMESTAMP
     *
     *
     * Scenario B: GENESIS_REWARDS_TIMESTAMP IS OUT OF RANGE
     *         <-----MAX_RETROACTIVE_LENGTH-----> t (block.timestamp) <---MAX_FUTURE_LENGTH--->
     *         <------------------------valid range for startTimestamp------------------------>
     *     ^
     * GENESIS_REWARDS_TIMESTAMP
     * @notice RewardsSubmission struct submitted by AVSs when making rewards for their operators and stakers
     * RewardsSubmission can be for a time range within the valid window for startTimestamp and must be within max duration.
     * See `createAVSRewardsSubmission()` for more details.
     * @param strategiesAndMultipliers The strategies and their relative weights
     * cannot have duplicate strategies and need to be sorted in ascending address order
     * @param token The rewards token to be distributed
     * @param amount The total amount of tokens to be distributed
     * @param startTimestamp The timestamp (seconds) at which the submission range is considered for distribution
     * could start in the past or in the future but within a valid range. See the diagram above.
     * @param duration The duration of the submission range in seconds. Must be <= MAX_REWARDS_DURATION
     */
    struct RewardsSubmission {
        StrategyAndMultiplier[] strategiesAndMultipliers;
        IERC20 token;
        uint256 amount;
        uint32 startTimestamp;
        uint32 duration;
    }

    /**
     * @notice A distribution root is a merkle root of the distribution of earnings for a given period.
     * The RewardsCoordinator stores all historical distribution roots so that earners can claim their earnings against older roots
     * if they wish but the merkle tree contains the cumulative earnings of all earners and tokens for a given period so earners (or their claimers if set)
     * only need to claim against the latest root to claim all available earnings.
     * @param root The merkle root of the distribution
     * @param rewardsCalculationEndTimestamp The timestamp (seconds) until which rewards have been calculated
     * @param activatedAt The timestamp (seconds) at which the root can be claimed against
     */
    struct DistributionRoot {
        bytes32 root;
        uint32 rewardsCalculationEndTimestamp;
        uint32 activatedAt;
        bool disabled;
    }

    /**
     * @notice Internal leaf in the merkle tree for the earner's account leaf
     * @param earner The address of the earner
     * @param earnerTokenRoot The merkle root of the earner's token subtree
     * Each leaf in the earner's token subtree is a TokenTreeMerkleLeaf
     */
    struct EarnerTreeMerkleLeaf {
        address earner;
        bytes32 earnerTokenRoot;
    }

    /**
     * @notice The actual leaves in the distribution merkle tree specifying the token earnings
     * for the respective earner's subtree. Each leaf is a claimable amount of a token for an earner.
     * @param token The token for which th

Tags:
ERC20, Multisig, Upgradeable, Multi-Signature, Factory, Oracle|addr:0x5a3e9f4fd0f4815a7106dfbe0a44aac339244ee6|verified:true|block:23626129|tx:0xd84eda6c453c0c7a0c73557261b5e5f968a2cb4f202754c6b2a60b298c88bcdc|first_check:1761055660

Submitted on: 2025-10-21 16:07:42

Comments

Log in to comment.

No comments yet.