Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unrestricted Asset Approval in NodeDelegator. #70

Closed
c4-submissions opened this issue Nov 11, 2023 · 6 comments
Closed

Unrestricted Asset Approval in NodeDelegator. #70

c4-submissions opened this issue Nov 11, 2023 · 6 comments
Labels
bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue grade-b insufficient quality report This report is not of sufficient quality primary issue Highest quality submission among a set of duplicates QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax

Comments

@c4-submissions
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-11-kelp/blob/c5fdc2e62c5e1d78769f44d6e34a6fb9e40c00f0/src/NodeDelegator.sol#L35-L46
https://github.com/code-423n4/2023-11-kelp/blob/c5fdc2e62c5e1d78769f44d6e34a6fb9e40c00f0/src/NodeDelegator.sol#L44
https://github.com/code-423n4/2023-11-kelp/blob/c5fdc2e62c5e1d78769f44d6e34a6fb9e40c00f0/src/NodeDelegator.sol#L45

Vulnerability details

Impact

The maxApproveToEigenStrategyManager function grants unlimited approval to an external contract to transfer assets from the NodeDelegator contract. This could allow loss of funds if the external contract is compromised.

Proof of Concept

maxApproveToEigenStrategyManager approves max amount of asset to external contract. No way to revoke allowance, so strategy manager contract can potentially drain assets.

The key issue is that it grants unlimited approval to the EigenStrategyManager external contract to transfer assets:

    /// @notice Approves the maximum amount of an asset to the eigen strategy manager
    /// @dev only supported assets can be deposited and only called by the LRT manager
    /// @param asset the asset to deposit
    function maxApproveToEigenStrategyManager(address asset)
        external
        override
        onlySupportedAsset(asset)
        onlyLRTManager
    {
        address eigenlayerStrategyManagerAddress = lrtConfig.getContract(LRTConstants.EIGEN_STRATEGY_MANAGER);
        IERC20(asset).approve(eigenlayerStrategyManagerAddress, type(uint256).max);
    }

The problems with this are:

  • There is no way to revoke or reset this unlimited allowance later

  • The external EigenStrategyManager could potentially drain assets from the NodeDelegator by transferring them to itself

  • If the EigenStrategyManager contract is compromised, the attacker could drain assets

The maxApproveToEigenStrategyManager function approves the maximum uint256 amount of an asset to the EigenStrategyManager address.

  • It fetches the EigenStrategyManager address from the LRTConfig contract: L44
address eigenlayerStrategyManagerAddress = 
  lrtConfig.getContract(LRTConstants.EIGEN_STRATEGY_MANAGER);
  • Then approves the max amount: L45
IERC20(asset).approve(
  eigenlayerStrategyManagerAddress, 
  type(uint256).max
);
  • There are access control checks, but no other limitations on the approval amount. once unlimited approval is granted to the external EigenStrategyManager contract, there is no way to revoke it.

The Issue

The maxApproveToEigenStrategyManager function in NodeDelegator provides unlimited approval to the external EigenStrategyManager contract, with no way to revoke it. This could allow the EigenStrategyManager to drain assets if compromised.

Impact

If the EigenStrategyManager contract is compromised, the attacker could:

  • Drain all assets from the NodeDelegator by transferring them to themselves
  • Manipulate integrations with the EigenLayer protocol
  • Cause loss of deposited funds

Trigger

This could be triggered by:

  • Finding an exploit in the EigenStrategyManager contract.
  • Separate vulnerability that allows taking over the EigenStrategyManager contract

Maximum impact

  • Function approves external contract to transfer unlimited amounts

  • External contract has balance of 1000 DAI

  • If compromised, attacker can drain all 1000 DAI

  • Maximum loss is full balance of given asset approved

A step-by-step explanation from root cause to impact

  1. NodeDelegator has 1000 DAI

  2. Attacker compromises external contract

  3. NodeDelegator calls maxApproveToEigenStrategyManager(DAI)

  4. Unlimited DAI approval granted to compromised contract

  5. Attacker uses external contract to transfer 1000 DAI to themselves

  6. Attacker has drained all 1000 DAI from NodeDelegator

Tools Used

Manual review

Recommended Mitigation Steps

  • Set a maximum approval amount cap
  • Build a revokeApproval function
  • Use increaseAllowance and decreaseAllowance instead
  • Validate EigenStrategyManager address being approved

Assessed type

ETH-Transfer

@c4-submissions c4-submissions added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Nov 11, 2023
c4-submissions added a commit that referenced this issue Nov 11, 2023
@c4-pre-sort c4-pre-sort added the insufficient quality report This report is not of sufficient quality label Nov 15, 2023
@c4-pre-sort
Copy link

raymondfam marked the issue as insufficient quality report

@c4-pre-sort c4-pre-sort added the primary issue Highest quality submission among a set of duplicates label Nov 15, 2023
@c4-pre-sort
Copy link

raymondfam marked the issue as primary issue

@raymondfam
Copy link

raymondfam commented Nov 15, 2023

Intended design callable only by the manager.

@fatherGoose1
Copy link

Agree that the max approval without ability to rescind approval adds risk, but the risk is accepted by Kelp. QA

@c4-judge
Copy link
Contributor

fatherGoose1 changed the severity to QA (Quality Assurance)

@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax grade-b and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Nov 29, 2023
@c4-judge
Copy link
Contributor

fatherGoose1 marked the issue as grade-b

@C4-Staff C4-Staff closed this as completed Dec 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue grade-b insufficient quality report This report is not of sufficient quality primary issue Highest quality submission among a set of duplicates QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
Projects
None yet
Development

No branches or pull requests

6 participants