DeFiFoundrySolidity
16,653 OP
View results
Submission Details
Severity: high
Invalid

Missing Rate-Limiting Mechanisms for Critical Functions

Summary

The claimAndSwap and setRouter functions in the StrategyOp contract lack rate-limiting mechanisms, exposing the strategy to risks such as rapid asset depletion, gas exhaustion, and operational disruptions. Without rate-limiting, these functions can be abused to manipulate strategy operations, disrupt functionality, or cause significant financial losses.

Mitigation includes implementing cooldown periods or time-based restrictions to ensure these critical functions cannot be executed excessively within short timeframes.


Technical Details

1. Code Reference

The affected functions currently lack rate-limiting mechanisms:

2. Workflow Context

  • claimAndSwap:

    • Swaps underlying tokens (WETH) for strategy assets (alETH).

    • Can be called by Keepers.

  • setRouter:

    • Updates the address of the router for token swaps.

    • Can be called by Management.

Issue:

These functions can be invoked repeatedly within short timeframes, leading to:

  1. Rapid Depletion of Funds:

    • Repeated swaps can exploit timing conditions or market volatility, draining strategy assets.

  2. Router Manipulation:

    • Frequent router updates disrupt operations and increase gas costs.

  3. Gas Limit Exhaustion:

    • Excessive calls lead to resource exhaustion, causing transaction failures and potential denial of service (DoS).


Exploitation Scenarios

Scenario 1: Rapid Swap Exploitation

  1. Setup:

    • The attacker has Keeper privileges to call claimAndSwap.

  2. Execution:

    • The attacker calls claimAndSwap repeatedly within milliseconds, exploiting market volatility or slippage conditions.

    for (uint256 i = 0; i < 100; i++) {
    strategy.claimAndSwap(_amountClaim, _minOut, _path);
    }
  3. Impact:

    • Strategy assets are rapidly drained due to repeated swaps, leading to significant financial loss.

Scenario 2: Router Flooding

  1. Setup:

    • A malicious Manager repeatedly calls setRouter to disrupt swap operations.

  2. Execution:

    for (uint256 i = 0; i < 50; i++) {
    strategy.setRouter(newRouterAddress);
    }
  3. Impact:

    • The strategy’s operations become unpredictable due to frequent router changes, increasing gas costs and operational inefficiency.

Scenario 3: Gas Limit Exhaustion

  1. Setup:

    • Repeated calls to either function within the same transaction.

  2. Impact:

    • Gas exhaustion leads to failed transactions, causing potential DoS conditions for the protocol.


Impact Analysis

Severity: Medium to High

  1. Financial Impact:

    • Rapid depletion of assets due to repeated swaps or router changes.

    • Quantifiable example: Repeated swaps drain 10,000 WETH, causing a loss of ~$20M (at $2,000/WETH).

  2. Operational Impact:

    • Frequent router updates disrupt the strategy’s functionality.

    • Gas exhaustion can cause DoS, blocking legitimate transactions.

  3. Reputational Impact:

    • Users lose trust in the protocol due to unpredictable operations and potential financial losses.


Root Cause Analysis

  1. Lack of Cooldown Mechanisms:

    • No restrictions are in place to limit the frequency of function calls.

  2. Insufficient Access Control:

    • While access control exists (onlyKeepers and onlyManagement), it does not prevent abuse by authorized actors.


Mitigation Recommendations

1. Implement Cooldown Mechanisms

  • introduce a cooldown period to enforce a minimum interval between consecutive calls:

    uint256 public lastClaimAndSwap;
    uint256 public constant CLAIM_AND_SWAP_COOLDOWN = 1 hours;
    function claimAndSwap(uint256 _amountClaim, uint256 _minOut, IRamsesRouter.route[] calldata _path) external onlyKeepers nonReentrant {
    require(block.timestamp >= lastClaimAndSwap + CLAIM_AND_SWAP_COOLDOWN, "Cooldown not met");
    lastClaimAndSwap = block.timestamp;
    // function body
    }
  • Similarly, for setRouter:

    uint256 public lastRouterChange;
    uint256 public constant ROUTER_CHANGE_COOLDOWN = 1 days;
    function setRouter(address _router) external onlyManagement {
    require(block.timestamp >= lastRouterChange + ROUTER_CHANGE_COOLDOWN, "Cooldown not met");
    lastRouterChange = block.timestamp;
    router = _router;
    underlying.safeApprove(router, type(uint256).max);
    }

** **

2. Add Rate-Limiting via Governance

  • Introduce governance-based limits for critical operations.


Proof of Concept (PoC)

** Reproduction:**

  1. Deploy the contract and grant Keeper privileges to an attacker.

  2. Execute repeated claimAndSwap calls within a short timeframe.

    for (uint256 i = 0; i < 100; i++) {
    strategy.claimAndSwap(_amountClaim, _minOut, _path);
    }
  3. Observe the rapid depletion of strategy assets or slippage exploitation.

Updates

Appeal created

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.