EigenAgentManager

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/EigenAgentManager.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

import { Access } from "../../../access/Access.sol";
import { IDelegation } from "../../../interfaces/IDelegation.sol";
import { IEigenAgentManager } from "../../../interfaces/IEigenAgentManager.sol";
import { IEigenServiceManager } from "../../../interfaces/IEigenServiceManager.sol";
import { ILender } from "../../../interfaces/ILender.sol";
import { IOracle } from "../../../interfaces/IOracle.sol";
import { IRateOracle } from "../../../interfaces/IRateOracle.sol";
import { IVault } from "../../../interfaces/IVault.sol";
import { EigenAgentManagerStorageUtils } from "../../../storage/EigenAgentManagerStorageUtils.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

/// @title EigenAgentManager
/// @author weso, Cap Labs
/// @notice Manages Eigen Agents
contract EigenAgentManager is IEigenAgentManager, UUPSUpgradeable, Access, EigenAgentManagerStorageUtils {
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    /// @inheritdoc IEigenAgentManager
    function initialize(
        address _accessControl,
        address _lender,
        address _cusd,
        address _delegation,
        address _serviceManager,
        address _oracle
    ) external initializer {
        __Access_init(_accessControl);
        __UUPSUpgradeable_init();
        EigenAgentManagerStorage storage $ = getEigenAgentManagerStorage();
        $.lender = _lender;
        $.cusd = _cusd;
        $.delegation = _delegation;
        $.serviceManager = _serviceManager;
        $.oracle = _oracle;
    }

    /// @inheritdoc IEigenAgentManager
    function addEigenAgent(AgentConfig calldata _agentConfig) external checkAccess(this.addEigenAgent.selector) {
        EigenAgentManagerStorage storage $ = getEigenAgentManagerStorage();

        /// 1. Add the agent to the delegation
        IDelegation($.delegation).addAgent(
            _agentConfig.agent, $.serviceManager, _agentConfig.ltv, _agentConfig.liquidationThreshold
        );

        /// 2. Add the agent to the network
        IEigenServiceManager($.serviceManager).registerStrategy(
            _agentConfig.strategy, _agentConfig.agent, _agentConfig.restaker, _agentConfig.operatorMetadata
        );

        /// 3. Add the agent to the rate oracle
        IRateOracle($.oracle).setRestakerRate(_agentConfig.agent, _agentConfig.delegationRate);
    }

    /// @inheritdoc IEigenAgentManager
    function setRestakerRate(address _agent, uint256 _delegationRate)
        external
        checkAccess(this.setRestakerRate.selector)
    {
        EigenAgentManagerStorage storage $ = getEigenAgentManagerStorage();
        address[] memory assets = IVault($.cusd).assets();
        for (uint256 i; i < assets.length; ++i) {
            (, uint256 unrealizedInterest) = ILender($.lender).maxRestakerRealization(_agent, assets[i]);
            if (unrealizedInterest > 0) {
                ILender($.lender).realizeRestakerInterest(_agent, assets[i]);
            }
        }

        IRateOracle($.oracle).setRestakerRate(_agent, _delegationRate);
    }

    /// @inheritdoc IEigenAgentManager
    function setServiceManager(address _serviceManager) external checkAccess(this.setServiceManager.selector) {
        EigenAgentManagerStorage storage $ = getEigenAgentManagerStorage();
        $.serviceManager = _serviceManager;
    }

    function _authorizeUpgrade(address) internal override checkAccess(bytes4(0)) { }
}
"
    },
    "contracts/access/Access.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

import { IAccess } from "../interfaces/IAccess.sol";
import { IAccessControl } from "../interfaces/IAccessControl.sol";

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

/// @title Access
/// @author kexley, Cap Labs
/// @notice Inheritable access
abstract contract Access is IAccess, Initializable, AccessStorageUtils {
    /// @dev Check caller has permissions for a function, revert if call is not allowed
    /// @param _selector Function selector
    modifier checkAccess(bytes4 _selector) {
        _checkAccess(_selector);
        _;
    }

    /// @dev Initialize the access control address
    /// @param _accessControl Access control address
    function __Access_init(address _accessControl) internal onlyInitializing {
        __Access_init_unchained(_accessControl);
    }

    /// @dev Initialize unchained
    /// @param _accessControl Access control address
    function __Access_init_unchained(address _accessControl) internal onlyInitializing {
        getAccessStorage().accessControl = _accessControl;
    }

    /// @dev Check caller has access to a function, revert overwise
    /// @param _selector Function selector
    function _checkAccess(bytes4 _selector) internal view {
        bool hasAccess =
            IAccessControl(getAccessStorage().accessControl).checkAccess(_selector, address(this), msg.sender);
        if (!hasAccess) revert AccessDenied();
    }
}
"
    },
    "contracts/interfaces/IDelegation.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

import { IRestakerRewardReceiver } from "./IRestakerRewardReceiver.sol";
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

/// @title IDelegation
/// @author weso, Cap Labs
/// @notice Interface for Delegation contract
interface IDelegation is IRestakerRewardReceiver {
    /// @dev Delegation storage
    /// @param agents Agent addresses
    /// @param agentData Agent data
    /// @param networks Network addresses
    /// @param oracle Oracle address
    /// @param epochDuration Epoch duration
    /// @param ltvBuffer LTV buffer from LT
    struct DelegationStorage {
        EnumerableSet.AddressSet agents;
        mapping(address => AgentData) agentData;
        EnumerableSet.AddressSet networks;
        address oracle;
        uint256 epochDuration;
        uint256 ltvBuffer;
        address feeRecipient;
    }

    /// @dev Agent data
    /// @param network Network address
    /// @param ltv Loan to value ratio
    /// @param liquidationThreshold Liquidation threshold
    /// @param lastBorrow Last borrow timestamp
    struct AgentData {
        address network;
        uint256 ltv;
        uint256 liquidationThreshold;
        uint256 lastBorrow;
    }

    /// @notice Slash a network
    /// @param network Network address
    /// @param slashShare Slash share
    event SlashNetwork(address network, uint256 slashShare);

    /// @notice Add an agent
    /// @param agent Agent address
    /// @param ltv LTV
    /// @param liquidationThreshold Liquidation threshold
    event AddAgent(address agent, address network, uint256 ltv, uint256 liquidationThreshold);

    /// @notice Modify an agent
    /// @param agent Agent address
    /// @param ltv LTV
    /// @param liquidationThreshold Liquidation threshold
    event ModifyAgent(address agent, uint256 ltv, uint256 liquidationThreshold);

    /// @notice Register a network
    /// @param network Network address
    event RegisterNetwork(address network);

    /// @notice Distribute a reward
    /// @param agent Agent address
    /// @param asset Asset address
    /// @param amount Amount
    event DistributeReward(address agent, address asset, uint256 amount);

    /// @notice Set the ltv buffer
    /// @param ltvBuffer LTV buffer
    event SetLtvBuffer(uint256 ltvBuffer);

    /// @notice Set the fee recipient
    /// @param feeRecipient Fee recipient
    event SetFeeRecipient(address feeRecipient);

    /// @notice Agent does not exist
    error AgentDoesNotExist();

    /// @notice Duplicate agent
    error DuplicateAgent();

    /// @notice Duplicate network
    error DuplicateNetwork();

    /// @notice Network already registered
    error NetworkAlreadyRegistered();

    /// @notice Network does not exist
    error NetworkDoesntExist();

    /// @notice Invalid liquidation threshold
    error InvalidLiquidationThreshold();

    /// @notice Liquidation threshold too close to ltv
    error LiquidationThresholdTooCloseToLtv();

    /// @notice Invalid ltv buffer
    error InvalidLtvBuffer();

    /// @notice Invalid network
    error InvalidNetwork();

    /// @notice No slashable collateral
    error NoSlashableCollateral();

    /// @notice Initialize the contract
    /// @param _accessControl Access control address
    /// @param _oracle Oracle address
    /// @param _epochDuration Epoch duration in seconds
    function initialize(address _accessControl, address _oracle, uint256 _epochDuration) external;

    /// @notice The slash function. Calls the underlying networks to slash the delegated capital
    /// @dev Called only by the lender during liquidation
    /// @param _agent The agent who is unhealthy
    /// @param _liquidator The liquidator who receives the funds
    /// @param _amount The USD value of the delegation needed to cover the debt
    function slash(address _agent, address _liquidator, uint256 _amount) external;

    /// @notice Distribute rewards to networks covering an agent proportionally to their coverage
    /// @param _agent The agent address
    /// @param _asset The reward token address
    function distributeRewards(address _agent, address _asset) external;

    /// @notice Set the last borrow timestamp for an agent
    /// @param _agent Agent address
    function setLastBorrow(address _agent) external;

    /// @notice Add agent to be delegated to
    /// @param _agent Agent address
    /// @param _network Network address
    /// @param _ltv Loan to value ratio
    /// @param _liquidationThreshold Liquidation threshold
    function addAgent(address _agent, address _network, uint256 _ltv, uint256 _liquidationThreshold) external;

    /// @notice Modify an agents config only callable by the operator
    /// @param _agent the agent to modify
    /// @param _ltv Loan to value ratio
    /// @param _liquidationThreshold Liquidation threshold
    function modifyAgent(address _agent, uint256 _ltv, uint256 _liquidationThreshold) external;

    /// @notice Register a new network
    /// @param _network Network address
    function registerNetwork(address _network) external;

    /// @notice Set the ltv buffer
    /// @param _ltvBuffer LTV buffer
    function setLtvBuffer(uint256 _ltvBuffer) external;

    /// @notice Set the fee recipient
    /// @param _feeRecipient Fee recipient
    function setFeeRecipient(address _feeRecipient) external;

    /// @notice Get the epoch duration
    /// @return duration Epoch duration in seconds
    /// @dev The duration between epochs. Pretty much the amount of time we have to slash the delegated collateral, if delegation is changed on the symbiotic vault.
    function epochDuration() external view returns (uint256 duration);

    /// @notice Get the current epoch
    /// @return currentEpoch Current epoch
    /// @dev Returns an epoch which we use to fetch the a timestamp in which we had slashable collateral. Will be less than the epoch on the symbiotic vault.
    function epoch() external view returns (uint256 currentEpoch);

    /// @notice Get the ltv buffer
    /// @return buffer LTV buffer
    function ltvBuffer() external view returns (uint256 buffer);

    /// @notice Get the timestamp that is most recent between the last borrow and the epoch -1
    /// @param _agent The agent address
    /// @return _slashTimestamp Timestamp that is most recent between the last borrow and the epoch -1
    function slashTimestamp(address _agent) external view returns (uint48 _slashTimestamp);

    /// @notice How much delegation and agent has available to back their borrows
    /// @param _agent The agent address
    /// @return delegation Amount in USD (8 decimals) that a agent has provided as delegation from the delegators
    function coverage(address _agent) external view returns (uint256 delegation);

    /// @notice How much slashable coverage an agent has available to back their borrows
    /// @param _agent The agent address
    /// @return _slashableCollateral Amount in USD (8 decimals) that a agent has provided as slashable collateral from the delegators
    function slashableCollateral(address _agent) external view returns (uint256 _slashableCollateral);

    /// @notice Fetch active network address
    /// @param _agent Agent address
    /// @return networkAddress network address
    function networks(address _agent) external view returns (address networkAddress);

    /// @notice Fetch active agent addresses
    /// @return agentAddresses Agent addresses
    function agents() external view returns (address[] memory agentAddresses);

    /// @notice The LTV of a specific agent
    /// @param _agent Agent who we are querying
    /// @return currentLtv Loan to value ratio of the agent
    function ltv(address _agent) external view returns (uint256 currentLtv);

    /// @notice Liquidation threshold of the agent
    /// @param _agent Agent who we are querying
    /// @return lt Liquidation threshold of the agent
    function liquidationThreshold(address _agent) external view returns (uint256 lt);

    /// @notice Check if a network exists
    /// @param _network Network address
    /// @return exists True if the network is registered
    function networkExists(address _network) external view returns (bool exists);

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

interface IEigenAgentManager {
    /// @dev EigenAgentManager storage
    /// @param delegation Delegation address
    /// @param serviceManager Service manager address
    /// @param oracle Oracle address
    /// @param lender Lender address
    /// @param cusd cUSD token address
    struct EigenAgentManagerStorage {
        address delegation;
        address serviceManager;
        address oracle;
        address lender;
        address cusd;
    }

    /// @dev Agent configuration
    /// @param agent Agent address
    /// @param strategy Strategy address
    /// @param avsMetadata AVS metadata
    /// @param operatorMetadata Operator metadata
    /// @param ltv LTV
    /// @param liquidationThreshold Liquidation threshold
    /// @param delegationRate Delegation rate
    struct AgentConfig {
        address agent;
        address strategy;
        address restaker;
        string avsMetadata;
        string operatorMetadata;
        uint256 ltv;
        uint256 liquidationThreshold;
        uint256 delegationRate;
    }

    /// @notice Initialize the agent manager
    /// @param _accessControl Access control address
    /// @param _lender Lender address
    /// @param _cusd cUSD token address
    /// @param _delegation Delegation address
    /// @param _serviceManager Service manager address
    /// @param _oracle Oracle address
    function initialize(
        address _accessControl,
        address _lender,
        address _cusd,
        address _delegation,
        address _serviceManager,
        address _oracle
    ) external;

    /// @notice Add an agent to the agent manager
    /// @param _agentConfig Agent configuration
    function addEigenAgent(AgentConfig calldata _agentConfig) external;

    /// @notice Set the restaker rate for an agent
    /// @param _agent Agent address
    /// @param _delegationRate Delegation rate
    function setRestakerRate(address _agent, uint256 _delegationRate) external;

    /// @notice Set the service manager
    /// @param _serviceManager Service manager address
    function setServiceManager(address _serviceManager) external;
}
"
    },
    "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/interfaces/ILender.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

/// @title ILender
/// @author kexley, Cap Labs
/// @notice Interface for the Lender contract
interface ILender {
    /// @dev Storage struct for the Lender contract
    /// @param delegation Address of the delegation contract that manages agent permissions
    /// @param oracle Address of the oracle contract used for price feeds
    /// @param reservesData Mapping of asset address to reserve data
    /// @param reservesList Mapping of reserve ID to asset address
    /// @param reservesCount Total number of reserves
    /// @param agentConfig Mapping of agent address to configuration
    /// @param liquidationStart Mapping of agent address to liquidation start time
    /// @param targetHealth Target health ratio for liquidations (scaled by 1e27)
    /// @param grace Grace period in seconds before an agent becomes liquidatable
    /// @param expiry Period in seconds after which liquidation rights expire
    /// @param bonusCap Maximum bonus percentage for liquidators (scaled by 1e27)
    /// @param emergencyLiquidationThreshold Health threshold below which grace periods are ignored
    struct LenderStorage {
        // Addresses
        address delegation;
        address oracle;
        // Reserve configuration
        mapping(address => ReserveData) reservesData;
        mapping(uint256 => address) reservesList;
        uint16 reservesCount;
        // Agent configuration
        mapping(address => AgentConfigurationMap) agentConfig;
        mapping(address => uint256) liquidationStart;
        // Liquidation parameters
        uint256 targetHealth;
        uint256 grace;
        uint256 expiry;
        uint256 bonusCap;
        uint256 emergencyLiquidationThreshold;
    }

    /// @dev Reserve data
    /// @param id Id of the reserve
    /// @param vault Address of the vault
    /// @param debtToken Address of the debt token
    /// @param interestReceiver Address of the interest receiver
    /// @param decimals Decimals of the asset
    /// @param paused True if the asset is paused, false otherwise
    /// @param debt Total debt of the asset
    /// @param totalUnrealizedInterest Total unrealized interest for the asset
    /// @param unrealizedInterest Unrealized interest for each agent
    /// @param lastRealizationTime Last time interest was realized for each agent
    /// @param minBorrow Minimum borrow amount for the asset
    struct ReserveData {
        uint256 id;
        address vault;
        address debtToken;
        address interestReceiver;
        uint8 decimals;
        bool paused;
        uint256 debt;
        uint256 totalUnrealizedInterest;
        mapping(address => uint256) unrealizedInterest;
        mapping(address => uint256) lastRealizationTime;
        uint256 minBorrow;
    }

    /// @dev Agent configuration map
    /// @param data Data of the agent configuration
    struct AgentConfigurationMap {
        uint256 data;
    }

    /// @dev Borrow parameters
    /// @param agent Address of the agent
    /// @param asset Asset to borrow
    /// @param amount Amount to borrow
    /// @param receiver Receiver of the borrowed asset
    /// @param maxBorrow True if the maximum amount is being borrowed, false otherwise
    struct BorrowParams {
        address agent;
        address asset;
        uint256 amount;
        address receiver;
        bool maxBorrow;
    }

    /// @dev Repay parameters
    /// @param agent Address of the agent
    /// @param asset Asset to repay
    /// @param amount Amount to repay
    /// @param caller Caller of the repay function
    struct RepayParams {
        address agent;
        address asset;
        uint256 amount;
        address caller;
    }

    /// @dev Realize restaker interest parameters
    /// @param agent Agent to realize interest for
    /// @param asset Asset to realize interest for
    struct RealizeRestakerInterestParams {
        address agent;
        address asset;
    }

    /// @dev Add asset parameters
    /// @param asset Asset to add
    /// @param vault Address of the vault
    /// @param debtToken Address of the debt token
    /// @param interestReceiver Address of the interest receiver
    /// @param bonusCap Bonus cap for liquidations
    struct AddAssetParams {
        address asset;
        address vault;
        address debtToken;
        address interestReceiver;
        uint256 bonusCap;
        uint256 minBorrow;
    }

    /// @dev Zero address not valid
    error ZeroAddressNotValid();

    /// @dev Invalid target health
    error InvalidTargetHealth();

    /// @dev Grace period greater than or equal to expiry
    error GraceGreaterThanExpiry();

    /// @dev Expiry less than or equal to grace
    error ExpiryLessThanGrace();

    /// @dev Invalid bonus cap
    error InvalidBonusCap();

    /// @notice Initialize the lender
    /// @param _accessControl Access control address
    /// @param _delegation Delegation address
    /// @param _oracle Oracle address
    /// @param _targetHealth Target health after liquidations
    /// @param _grace Grace period before an agent becomes liquidatable
    /// @param _expiry Expiry period after which an agent cannot be liquidated until called again
    /// @param _bonusCap Bonus cap for liquidations
    /// @param _emergencyLiquidationThreshold Liquidation threshold below which grace periods are voided
    function initialize(
        address _accessControl,
        address _delegation,
        address _oracle,
        uint256 _targetHealth,
        uint256 _grace,
        uint256 _expiry,
        uint256 _bonusCap,
        uint256 _emergencyLiquidationThreshold
    ) external;

    /// @notice Borrow an asset
    /// @param _asset Asset to borrow
    /// @param _amount Amount to borrow
    /// @param _receiver Receiver of the borrowed asset
    /// @return borrowed Actual amount borrowed
    function borrow(address _asset, uint256 _amount, address _receiver) external returns (uint256 borrowed);

    /// @notice Repay an asset
    /// @param _asset Asset to repay
    /// @param _amount Amount to repay
    /// @param _agent Repay on behalf of another borrower
    /// @return repaid Actual amount repaid
    function repay(address _asset, uint256 _amount, address _agent) external returns (uint256 repaid);

    /// @notice Realize interest for an asset
    /// @param _asset Asset to realize interest for
    /// @return actualRealized Actual amount realized
    function realizeInterest(address _asset) external returns (uint256 actualRealized);

    /// @notice Realize interest for restaker debt of an agent for an asset
    /// @param _agent Agent to realize interest for
    /// @param _asset Asset to realize interest for
    /// @return actualRealized Actual amount realized
    function realizeRestakerInterest(address _agent, address _asset) external returns (uint256 actualRealized);

    /// @notice Open liquidation window of an agent when the health is below 1
    /// @param _agent Agent address
    function openLiquidation(address _agent) external;

    /// @notice Close liquidation window of an agent when the health is above 1
    /// @param _agent Agent address
    function closeLiquidation(address _agent) external;

    /// @notice Liquidate an agent when the health is below 1
    /// @param _agent Agent address
    /// @param _asset Asset to repay
    /// @param _amount Amount of asset to repay on behalf of the agent
    /// @param _minLiquidatedValue Minimum value of the liquidation returned to the liquidator
    /// @return liquidatedValue Value of the liquidation returned to the liquidator
    function liquidate(address _agent, address _asset, uint256 _amount, uint256 _minLiquidatedValue)
        external
        returns (uint256 liquidatedValue);

    /// @notice Add an asset to the Lender
    /// @param _params Parameters to add an asset
    function addAsset(AddAssetParams calldata _params) external;

    /// @notice Remove asset from lending when there is no borrows
    /// @param _asset Asset address
    function removeAsset(address _asset) external;

    /// @notice Pause an asset from being borrowed
    /// @param _asset Asset address
    /// @param _pause True if pausing or false if unpausing
    function pauseAsset(address _asset, bool _pause) external;

    /// @notice Set the interest receiver for an asset
    /// @param _asset Asset address
    /// @param _interestReceiver Interest receiver address
    function setInterestReceiver(address _asset, address _interestReceiver) external;

    /// @notice Set the minimum borrow amount for an asset
    /// @param _asset Asset address
    /// @param _minBorrow Minimum borrow amount in asset decimals
    function setMinBorrow(address _asset, uint256 _minBorrow) external;

    /// @notice Set the grace period
    /// @param _grace Grace period in seconds
    function setGrace(uint256 _grace) external;

    /// @notice Set the expiry period
    /// @param _expiry Expiry period in seconds
    function setExpiry(uint256 _expiry) external;

    /// @notice Set the bonus cap
    /// @param _bonusCap Bonus cap in percentage ray decimals
    function setBonusCap(uint256 _bonusCap) external;

    /// @notice Get the accrued restaker interest for an agent for a specific asset
    /// @param _agent Agent address to check accrued restaker interest for
    /// @param _asset Asset to check accrued restaker interest for
    /// @return accruedInterest Accrued restaker interest in asset decimals
    function accruedRestakerInterest(address _agent, address _asset) external view returns (uint256 accruedInterest);

    /// @notice Get the total number of reserves
    /// @return count Number of reserves
    function reservesCount() external view returns (uint256 count);

    /// @notice Calculate the agent data
    /// @param _agent Address of agent
    /// @return totalDelegation Total delegation of an agent in USD, encoded with 8 decimals
    /// @return totalSlashableCollateral Total slashable collateral of an agent in USD, encoded with 8 decimals
    /// @return totalDebt Total debt of an agent in USD, encoded with 8 decimals
    /// @return ltv Loan to value ratio, encoded in ray (1e27)
    /// @return liquidationThreshold Liquidation ratio of an agent, encoded in ray (1e27)
    /// @return health Health status of an agent, encoded in ray (1e27)
    function agent(address _agent)
        external
        view
        returns (
            uint256 totalDelegation,
            uint256 totalSlashableCollateral,
            uint256 totalDebt,
            uint256 ltv,
            uint256 liquidationThreshold,
            uint256 health
        );

    /// @notice Get the bonus cap
    /// @return bonusCap Bonus cap in percentage ray decimals
    function bonusCap() external view returns (uint256 bonusCap);

    /// @notice Get the current debt balances for an agent for a specific asset
    /// @param _agent Agent address to check debt for
    /// @param _asset Asset to check debt for
    /// @return totalDebt Total debt amount in asset decimals
    function debt(address _agent, address _asset) external view returns (uint256 totalDebt);

    /// @notice Calculate the maximum interest that can be realized
    /// @param _asset Asset to calculate max realization for
    /// @return _maxRealization Maximum interest that can be realized
    function maxRealization(address _asset) external view returns (uint256 _maxRealization);

    /// @notice Calculate the maximum interest that can be realized for a restaker
    /// @param _agent Agent to calculate max realization for
    /// @param _asset Asset to calculate max realization for
    /// @return newRealizedInterest Maximum interest that can be realized
    /// @return newUnrealizedInterest Unrealized interest that will be added to the debt
    function maxRestakerRealization(address _agent, address _asset)
        external
        view
        returns (uint256 newRealizedInterest, uint256 newUnrealizedInterest);

    /// @notice Get the emergency liquidation threshold
    function emergencyLiquidationThreshold() external view returns (uint256 emergencyLiquidationThreshold);

    /// @notice Get the expiry period
    /// @return expiry Expiry period in seconds
    function expiry() external view returns (uint256 expiry);

    /// @notice Get the grace period
    /// @return grace Grace period in seconds
    function grace() external view returns (uint256 grace);

    /// @notice Get the target health ratio
    /// @return targetHealth Target health ratio scaled to 1e27
    function targetHealth() external view returns (uint256 targetHealth);

    /// @notice The liquidation start time for an agent
    /// @param _agent Address of the agent
    /// @return startTime Timestamp when liquidation was initiated
    function liquidationStart(address _agent) external view returns (uint256 startTime);

    /// @notice Calculate the maximum amount that can be borrowed for a given asset
    /// @param _agent Agent address
    /// @param _asset Asset to borrow
    /// @return maxBorrowableAmount Maximum amount that can be borrowed in asset decimals
    function maxBorrowable(address _agent, address _asset) external view returns (uint256 maxBorrowableAmount);

    /// @notice Calculate the maximum amount that can be liquidated for a given asset
    /// @param _agent Agent address
    /// @param _asset Asset to liquidate
    /// @return maxLiquidatableAmount Maximum amount that can be liquidated in asset decimals
    function maxLiquidatable(address _agent, address _asset) external view returns (uint256 maxLiquidatableAmount);

    /// @notice Calculate the maximum bonus for a liquidation in percentage ray decimals
    /// @param _agent Agent address
    /// @return maxBonus Maximum bonus in percentage ray decimals
    function bonus(address _agent) external view returns (uint256 maxBonus);

    /// @notice The reserve data for an asset
    /// @param _asset Address of the asset
    /// @return id Id of the reserve
    /// @return vault Address of the vault
    /// @return debtToken Address of the debt token
    /// @return interestReceiver Address of the interest receiver
    /// @return decimals Decimals of the asset
    /// @return paused True if the asset is paused, false otherwise
    function reservesData(address _asset)
        external
        view
        returns (
            uint256 id,
            address vault,
            address debtToken,
            address interestReceiver,
            uint8 decimals,
            bool paused,
            uint256 minBorrow
        );

    /// @notice Get the unrealized restaker interest for an agent for a specific asset
    /// @dev This amount was not yet realized due to low reserves for the asset
    /// @param _agent Agent address
    /// @param _asset Asset to check unrealized interest for
    /// @return _unrealizedInterest Unrealized interest in asset decimals
    function unrealizedInterest(address _agent, address _asset) external view returns (uint256 _unrealizedInterest);
}
"
    },
    "contracts/interfaces/IOracle.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

import { IPriceOracle } from "./IPriceOracle.sol";
import { IRateOracle } from "./IRateOracle.sol";

/// @title Oracle
/// @author kexley, Cap Labs
/// @notice Price and rate oracles are unified
interface IOracle is IPriceOracle, IRateOracle {
    /// @notice Initialize the oracle
    /// @param _accessControl Access control address
    function initialize(address _accessControl) external;
}
"
    },
    "contracts/interfaces/IRateOracle.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

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

/// @title IRateOracle
/// @author kexley, Cap Labs
/// @notice Interface for the rate oracle
interface IRateOracle is IOracleTypes {
    /// @dev Storage for the rate oracle
    /// @param marketOracleData Oracle data for the market rate
    /// @param utilizationOracleData Oracle data for the utilization rate
    /// @param benchmarkRate Benchmark rate for each asset
    /// @param restakerRate Restaker rate for each agent
    struct RateOracleStorage {
        mapping(address => IOracleTypes.OracleData) marketOracleData;
        mapping(address => IOracleTypes.OracleData) utilizationOracleData;
        mapping(address => uint256) benchmarkRate;
        mapping(address => uint256) restakerRate;
    }

    /// @dev Set market oracle data
    event SetMarketOracleData(address asset, IOracleTypes.OracleData data);

    /// @dev Set utilization oracle data
    event SetUtilizationOracleData(address asset, IOracleTypes.OracleData data);

    /// @dev Set benchmark rate
    /// @dev Rate value is encoded in ray (27 decimals) and encodes yearly rates
    event SetBenchmarkRate(address asset, uint256 rate);

    /// @dev Set restaker rate
    /// @dev Rate value is encoded in ray (27 decimals) and encodes yearly rates
    event SetRestakerRate(address agent, uint256 rate);

    /// @notice Set a market source for an asset
    /// @param _asset Asset address
    /// @param _oracleData Oracle data
    function setMarketOracleData(address _asset, IOracleTypes.OracleData calldata _oracleData) external;

    /// @notice Set a utilization source for an asset
    /// @param _asset Asset address
    /// @param _oracleData Oracle data
    function setUtilizationOracleData(address _asset, IOracleTypes.OracleData calldata _oracleData) external;

    /// @notice Update the minimum interest rate for an asset
    /// @dev Rate value is encoded in ray (27 decimals) and encodes yearly rates
    /// @param _asset Asset address
    /// @param _rate New interest rate
    function setBenchmarkRate(address _asset, uint256 _rate) external;

    /// @notice Update the rate at which an agent accrues interest explicitly to pay restakers
    /// @dev Rate value is encoded in ray (27 decimals) and encodes yearly rates
    /// @param _agent Agent address
    /// @param _rate New interest rate
    function setRestakerRate(address _agent, uint256 _rate) external;

    /// @notice Fetch the market rate for an asset being borrowed
    /// @dev Rate value is encoded in ray (27 decimals) and encodes yearly rates
    /// @param _asset Asset address
    /// @return rate Borrow interest rate
    function marketRate(address _asset) external returns (uint256 rate);

    /// @notice View the utilization rate for an asset
    /// @dev Rate value is encoded in ray (27 decimals) and encodes yearly rates
    /// @param _asset Asset address
    /// @return rate Utilization rate
    function utilizationRate(address _asset) external returns (uint256 rate);

    /// @notice View the benchmark rate for an asset
    /// @dev Rate value is encoded in ray (27 decimals) and encodes yearly rates
    /// @param _asset Asset address
    /// @return rate Benchmark rate
    function benchmarkRate(address _asset) external view returns (uint256 rate);

    /// @notice View the restaker rate for an agent
    /// @dev Rate value is encoded in ray (27 decimals) and encodes yearly rates
    /// @param _agent Agent address
    /// @return rate Restaker rate
    function restakerRate(address _agent) external view returns (uint256 rate);

    /// @notice View the market oracle data for an asset
    /// @param _asset Asset address
    /// @return data Oracle data for an asset
    function marketOracleData(address _asset) external view returns (IOracleTypes.OracleData memory data);

    /// @notice View the utilization oracle data for an asset
    /// @param _asset Asset address
    /// @return data Oracle data for an asset
    function utilizationOracleData(address _asset) external view returns (IOracleTypes.OracleData memory data);
}
"
    },
    "contracts/interfaces/IVault.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

/// @title Vault interface for storing the backing for cTokens
/// @author kexley, Cap Labs
/// @notice Interface for the Vault contract which handles supplies, borrows and utilization tracking
interface IVault {
    /// @dev Storage for the vault
    /// @param assets List of assets
    /// @param totalSupplies Total supplies of an asset
    /// @param totalBorrows Total borrows of an asset
    /// @param utilizationIndex Utilization index of an asset
    /// @param lastUpdate Last update time of an asset
    /// @param paused Pause state of an asset
    /// @param insuranceFund Insurance fund address
    struct VaultStorage {
        EnumerableSet.AddressSet assets;
        mapping(address => uint256) totalSupplies;
        mapping(address => uint256) totalBorrows;
        mapping(address => uint256) utilizationIndex;
        mapping(address => uint256) lastUpdate;
        mapping(address => bool) paused;
        address insuranceFund;
    }

    /// @dev Parameters for minting or burning
    /// @param asset Asset to mint or burn
    /// @param amountIn Amount of asset to use in the minting or burning
    /// @param amountOut Amount of cap token to mint or burn
    /// @param minAmountOut Minimum amount to mint or burn
    /// @param receiver Receiver of the minting or burning
    /// @param deadline Deadline of the tx
    /// @param fee Fee paid to the insurance fund
    struct MintBurnParams {
        address asset;
        uint256 amountIn;
        uint256 amountOut;
        uint256 minAmountOut;
        address receiver;
        uint256 deadline;
        uint256 fee;
    }

    /// @dev Parameters for redeeming
    /// @param amountIn Amount of cap token to burn
    /// @param amountsOut Amounts of assets to withdraw
    /// @param minAmountsOut Minimum amounts of assets to withdraw
    /// @param receiver Receiver of the withdrawal
    /// @param deadline Deadline of the tx
    /// @param fees Fees paid to the insurance fund
    struct RedeemParams {
        uint256 amountIn;
        uint256[] amountsOut;
        uint256[] minAmountsOut;
        address receiver;
        uint256 deadline;
        uint256[] fees;
    }

    /// @dev Parameters for borrowing
    /// @param asset Asset to borrow
    /// @param amount Amount of asset to borrow
    /// @param receiver Receiver of the borrow
    struct BorrowParams {
        address asset;
        uint256 amount;
        address receiver;
    }

    /// @dev Parameters for repaying
    /// @param asset Asset to repay
    /// @param amount Amount of asset to repay
    struct RepayParams {
        address asset;
        uint256 amount;
    }

    /// @notice Mint the cap token using an asset
    /// @dev This contract must have approval to move asset from msg.sender
    /// @param _asset Whitelisted asset to deposit
    /// @param _amountIn Amount of asset to use in the minting
    /// @param _minAmountOut Minimum amount to mint
    /// @param _receiver Receiver of the minting
    /// @param _deadline Deadline of the tx
    function mint(address _asset, uint256 _amountIn, uint256 _minAmountOut, address _receiver, uint256 _deadline)
        external
        returns (uint256 amountOut);

    /// @notice Burn the cap token for an asset
    /// @dev Asset is withdrawn from the reserve or divested from the underlying vault
    /// @param _asset Asset to withdraw
    /// @param _amountIn Amount of cap token to burn
    /// @param _minAmountOut Minimum amount out to receive
    /// @param _receiver Receiver of the withdrawal
    /// @param _deadline Deadline of the tx
    function burn(address _asset, uint256 _amountIn, uint256 _minAmountOut, address _receiver, uint256 _deadline)
        external
        returns (uint256 amountOut);

    /// @notice Redeem the Cap token for a bundle of assets
    /// @dev Assets are withdrawn from the reserve or divested from the underlying vault
    /// @param _amountIn Amount of Cap token to burn
    /// @param _minAmountsOut Minimum amounts of assets to withdraw
    /// @param _receiver Receiver of the withdrawal
    /// @param _deadline Deadline of the tx
    /// @return amountsOut Amount of assets withdrawn
    function redeem(uint256 _amountIn, uint256[] calldata _minAmountsOut, address _receiver, uint256 _deadline)
        external
        returns (uint256[] memory amountsOut);

    /// @notice Borrow an asset
    /// @dev Whitelisted agents can borrow any amount, LTV is handled by Agent contracts
    /// @param _asset Asset to borrow
    /// @param _amount Amount of asset to borrow
    /// @param _receiver Receiver of the borrow
    function borrow(address _asset, uint256 _amount, address _receiver) external;

    /// @notice Repay an asset
    /// @param _asset Asset to repay
    /// @param _amount Amount of asset to repay
    function repay(address _asset, uint256 _amount) external;

    /// @notice Add an asset to the vault list
    /// @param _asset Asset address
    function addAsset(address _asset) external;

    /// @notice Remove an asset from the vault list
    /// @param _asset Asset address
    function removeAsset(address _asset) external;

    /// @notice Pause an asset
    /// @param _asset Asset address
    function pauseAsset(address _asset) external;

    /// @notice Unpause an asset
    /// @param _asset Asset address
    function unpauseAsset(address _asset) external;

    /// @notice Pause all protocol operations
    function pauseProtocol() external;

    /// @notice Unpause all protocol operations
    function unpauseProtocol() external;

    /// @notice Set the insurance fund
    /// @param _insuranceFund Insurance fund address
    function setInsuranceFund(address _insuranceFund) external;

    /// @notice Rescue an unsupported asset
    /// @param _asset Asset to rescue
    /// @param _receiver Receiver of the rescue
    function rescueERC20(address _asset, address _receiver) external;

    /// @notice Get the list of assets supported by the vault
    /// @return assetList List of assets
    function assets() external view returns (address[] memory assetList);

    /// @notice Get the total supplies of an asset
    /// @param _asset Asset address
    /// @return totalSupply Total supply
    function totalSupplies(address _asset) external view returns (uint256 totalSupply);

    /// @notice Get the total borrows of an asset
    /// @param _asset Asset address
    /// @return totalBorrow Total borrow
    function totalBorrows(address _asset) external view returns (uint256 totalBorrow);

    /// @notice Get the pause state of an asset
    /// @param _asset Asset address
    /// @return isPaused Pause state
    function paused(address _asset) external view returns (bool isPaused);

    /// @notice Available balance to borrow
    /// @param _asset Asset to borrow
    /// @return amount Amount available
    function availableBalance(address _asset) external view returns (uint256 amount);

    /// @notice Utilization rate of an asset
    /// @dev Utilization scaled by 1e27
    /// @param _asset Utilized asset
    /// @return ratio Utilization ratio
    function utilization(address _asset) external view returns (uint256 ratio);

    /// @notice Up to date cumulative utilization index of an asset
    /// @dev Utilization scaled by 1e27
    /// @param _asset Utilized asset
    /// @return index Utilization ratio index
    function currentUtilizationIndex(address _asset) external view returns (uint256 index);

    /// @notice Get the insurance fund
    /// @return insuranceFund Insurance fund
    function insuranceFund() external view returns (address);
}
"
    },
    "contracts/storage/EigenAgentManagerStorageUtils.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

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

/// @title Eigen Agent Manager Storage Utils
/// @author weso, Cap Labs
/// @notice Storage utilities for eigen agent manager
abstract contract EigenAgentManagerStorageUtils {
    /// @dev keccak256(abi.encode(uint256(keccak256("cap.storage.EigenAgentManager")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant EigenAgentManagerStorageLocation =
        0xfd8e9c49b112daf0453bd851da4ce96c57ae33d01ffa80f8eb965653c5ff1200;

    /// @dev Get eigen agent manager storage
    /// @return $ Storage pointer
    function getEigenAgentManagerStorage()
        internal
        pure
        returns (IEigenAgentManager.EigenAgentManagerStorage storage $)
    {
        assembly {
            $.slot := EigenAgentManagerStorageLocation
        }
    }
}
"
    },
    "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/UUPSUpgradeable.sol)

pragma solidity ^0.8.22;

import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {Initializable} from "./Initializable.sol";

/**
 * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
 * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
 *
 * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
 * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
 * `UUPSUpgradeable` with a custom implementation of upgrades.
 *
 * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
 */
abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
    address private immutable __self = address(this);

    /**
     * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
     * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
     * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
     * If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
     * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
     * during an upgrade.
     */
    string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";

    /**
     * @dev The call is from an unauthorized context.
     */
    error UUPSUnauthorizedCallContext();

    /**
     * @dev The storage `slot` is unsupported as a UUID.
     */
    error UUPSUnsupportedProxiableUUID(bytes32 slot);

    /**
     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
     * a proxy contract with an implementation (as defined in ERC-1967) pointing to self. This should only be the case
     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
     * function through ERC-1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
     * fail.
     */
    modifier onlyProxy() {
        _checkProxy();
        _;
    }

    /**
     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
     * callable on the implementing contract but not through proxies.
     */
    modifier notDelegated() {
        _checkNotDelegated();
        _;
    }

    function __UUPSUpgradeable_init() internal onlyInitializing {
    }

    function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
    }
    /**
     * @dev Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the
     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.
     *
     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
     */
    function proxiableUUID() external view virtual notDelegated returns (bytes32) {
        return ERC1967Utils.IMPLEMENTATION_SLOT;
    }

    /**
     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
     * encoded in `data`.
     *
     * Calls {_authorizeUpgrade}.
     *
     * Emits an {Upgraded} event.
     *
     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
     */
    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallUUPS(newImplementation, data);
    }

    /**
     * @dev Reverts if the execution is not performed via delegatecall or the execution
     * context is not of a proxy with an ERC-1967 compliant implementation pointing to self.
     */
    function _checkProxy() internal view virtual {
        if (
            address(this) == __self || // Must be called through delegatecall
            ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
        ) {
            revert UUPSUnauthorizedCallContext();
        }
    }

    /**
     * @dev Reverts if the execution is performed via delegatecall.
     * See {notDelegated}.
     */
    function _checkNotDelegated() internal view virtual {
        if (address(this) != __self) {
            // Must not be called through delegatecall
            revert UUPSUnauthorizedCallContext();
        }
    }

    /**
     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
     * {upgradeToAndCall}.
     *
     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
     *
     * ```solidity
     * function _authorizeUpgrade(address) internal onlyOwner {}
     * ```
     */
    function _authorizeUpgrade(address newImplementation) internal virtual;

    /**
     * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
     *
     * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
     * is expected to be the implementation slot in ERC-1967.
     *
     * Emits an {IERC1967-Upgraded} event.
     */
    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
        try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
            if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
                revert UUPSUnsupportedProxiableUUID(slot);
            }
            ERC1967Utils.upgradeToAndCall(newImplementation, data);
        } catch {
            // The implementation is not UUPS
            revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
        }
    }
}
"
    },
    "contracts/interfaces/IAccess.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

/// @title IAccess
/// @author kexley, Cap Labs
/// @notice Interface for Access contract
interface IAccess {
    /// @dev Access storage
    /// @param accessControl Access control address
    struct AccessStorage {
        address accessControl;
    }

    /// @notice Access is denied for the caller
    error AccessDenied();
}
"
    },
    "contracts/interfaces/IAccessControl.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

/// @title IAccessControl
/// @author kexley, Cap Labs
/// @notice Interface for granular access control system that manages permissions for specific function selectors on contracts
interface IAccessControl {
    /// @notice Error thrown when trying to revoke own revocation role
    error CannotRevokeSelf();

    /// @notice Initialize the access control system with a default admin
    /// @param _admin Address to be granted the default admin role and initial access management permissions
    function initialize(address _admin) external;

    /// @notice Grant access to a specific method on a contract
    /// @param _selector Function selector (4-byte identifier) of the method to grant access to
    /// @param _contract Address of the contract containing the method
    /// @param _address Address to grant access to
    function grantAccess(bytes4 _selector, address _contract, address _address) external;

    /// @notice Revoke access to a specific method on a contract
    /// @param _selector Function selector (4-byte identifier) of the method to revoke access from
    /// @param _contract Address of the contract containing the method
    /// @param _address Address to revoke access from
    function revokeAccess(bytes4 _selector, address _contract, address _address) external;

    /// @notice Check if a specific method access is granted to an address
    /// @param _selector 

Tags:
ERC20, Multisig, Mintable, Burnable, Swap, Upgradeable, Multi-Signature, Factory, Oracle|addr:0x0fc2153d1455d5a02555413d88a352787abe0268|verified:true|block:23634698|tx:0x4e31c6337929ae58d3def1732515a8ac4091bdf2eec4be19d6e3529522e8d7b6|first_check:1761291827

Submitted on: 2025-10-24 09:43:50

Comments

Log in to comment.

No comments yet.