WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Soaring Foggy Dalmatian - Compromised admin keys allow a malicious adapter to siphon off slippage differences from user swaps #727

@sherlock-admin4

Description

@sherlock-admin4

Soaring Foggy Dalmatian

Medium

Compromised admin keys allow a malicious adapter to siphon off slippage differences from user swaps

Summary

The unrestricted setAdapter in DexSwap.sol allows a compromised admin to register a malicious adapter that performs a normal swap but then calculates the “slippage difference” (the excess above the user’s minAmountOut) and redirects that excess to the attacker, causing users to lose value even though their swap succeeds within slippage bounds.


Root Cause

In DexSwap.sol (around line 47), setAdapter(aggregatorId, addr, selector):

  • Allows any single admin to register an arbitrary adapter contract without timelock or multi‑sig
  • Trusts the adapter’s implementation of executeSimpleSwap to be honest
    A malicious adapter can therefore implement the same swap call but, after the swap, transfer any tokens above the user’s minAmountOut to the attacker.

Internal Pre‑conditions

  1. The attacker obtains one admin’s private key.
  2. Attacker calls dexSwap.setAdapter("SLIP", maliciousAddr, maliciousSelector).

External Pre‑conditions

  1. Users invoke swaps using aggregator ID "SLIP", either via front‑end manipulation or direct calldata.
  2. Front‑end does not restrict aggregator IDs or verify adapter addresses on‑chain.

Attack Path

  1. Attacker (as admin) registers:

    dexSwap.setAdapter(
      "SLIP",
      0xBadAdapter…,
      MaliciousAdapter.executeSimpleSwap.selector
    );
  2. User executes:

    dexSwap.swap(
      SwapParams({
        aggregatorId: "SLIP",
        fromToken: USDC,
        fromTokenAmount: 1_000e6,
        toToken: DAI,
        minAmountOut: 995e18,
        feeRate: 0,
        feeOnFromToken: false,
        feeReceiver: address(0),
        data: /* normal Uniswap payload */
      })
    );
  3. MaliciousAdapter delegatecalls Uniswap to perform the 1,000 USDC→1,000 DAI swap, then:

    • Computes actualOut = DAI.balanceOf(address(this)) – preSwapBalance (≈1,000 DAI)
    • Calculates slippageGain = actualOut – params.minAmountOut (≈5 DAI)
    • Transfers slippageGain (5 DAI) to attacker’s wallet, then forwards the remaining 995 DAI to the user.

Impact

Swap users lose the full slippage margin (e.g. ~5 DAI on a 1,000 USDC→995 DAI swap), which:

  • Exceeds “relevant loss” thresholds (>0.01% & >$10) when the swap size is large enough
  • Constitutes a direct and non‑obvious fund diversion despite successful swap execution

This qualifies as High severity under “direct loss of funds” due to malicious routing of slippage.


PoC

See Vulnerability Path


Mitigation

  • Timelock/Multi‑Sig: Require multiple admin confirmations or a timelock before setAdapter takes effect.
  • Adapter Verification: On‑chain enforce that only pre‑approved adapter addresses (and selectors) can be used.
  • Front‑end Safeguards: Hardcode allowed aggregator IDs & adapter addresses in the UI and reject any unexpected values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions