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

`claimAndSwap` Exposed to Funds Drain

Summary

The claimAndSwap function in StrategyMainnet is vulnerable to reentrancy attacks due to multiple external calls (transmuter.claim, router.exchange, transmuter.deposit) without safeguards. This allows attackers to exploit the function through reentrant calls, manipulating the contract state or draining funds. Mitigation requires reentrancy guards, improved function design, and restricted external interactions.


Technical Details

Root Cause

  • The function performs external calls to the transmuter and router without locking its state.

  • It checks balances (balBefore and balAfter) post-execution, making them susceptible to manipulation during reentrant calls.

Vulnerable Code

function claimAndSwap(
uint256 _amountClaim,
uint256 _minOut,
uint256 _routeNumber
) external onlyKeepers {
transmuter.claim(_amountClaim, address(this)); // External call
uint256 balBefore = asset.balanceOf(address(this));
router.exchange( // External call
routes[_routeNumber],
swapParams[_routeNumber],
_amountClaim,
_minOut,
pools[_routeNumber],
address(this)
);
uint256 balAfter = asset.balanceOf(address(this));
require((balAfter - balBefore) >= _minOut, "Slippage too high");
transmuter.deposit(asset.balanceOf(address(this)), address(this)); // External call
}

Attack Scenarios

Scenario: Reentrancy Attack via Malicious Router

  1. Setup:

    • An attacker sets a malicious router address via setRouter (centralized risk).

  2. Execution:

    • During router.exchange, the malicious router re-enters claimAndSwap via another transaction, triggering recursive execution.

  3. Impact:

    • Funds are drained through repeated swaps.

    • Balance checks (balBefore, balAfter) are bypassed, making validation ineffective.

Additional Risks:

State Manipulation: Manipulated deposits disrupt accounting for user shares and yields.

Potential Denial of Service (DoS): Infinite loops could exhaust gas, disrupting operations.


Impact

  1. Financial Loss: Draining funds from the contract through recursive execution.

  2. Operational Disruption: Broken accounting due to manipulated balances.

  3. Reputation Damage: Loss of trust in the protocol’s security.


Mitigation Recommendations

  1. Reentrancy Guard:

    • Use OpenZeppelin’s ReentrancyGuard to prevent reentrant calls.

    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
    contract StrategyMainnet is ReentrancyGuard {
    function claimAndSwap(
    uint256 _amountClaim,
    uint256 _minOut,
    uint256 _routeNumber
    ) external onlyKeepers nonReentrant {
    // Function body
    }
    }
  2. Follow the Checks-Effects-Interactions Pattern:

    • Update contract state (e.g., balance deductions) before external calls:

    function claimAndSwap(...) external onlyKeepers nonReentrant {
    balances[address(this)] -= _amountClaim; // Update state first
    router.exchange(...); // External call
    }
Updates

Appeal created

inallhonesty Lead Judge 7 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.