All incidents

MachineShare CurveStableSwapNG mispricing arbitrage extracts ETH-side liquidity

Share
Jan 20, 2026 03:40 UTCMEVGain: 5,108,973.34 USDCManually checked1 exploit txWindow: Atomic

Root Cause Analysis

MachineShare CurveStableSwapNG mispricing arbitrage extracts ETH-side liquidity

1. Incident Overview TL;DR

On Ethereum mainnet block 24273362, a searcher-controlled account cluster executed a single attacker-crafted transaction (0x569733b8016ef9418f0b6bde8c14224d9e759e79301499908ecbcd956a0651f5) that flash-borrowed USDC via Morpho and routed liquidity through MachineShare, the MachineShare/USDC CurveStableSwapNG pool, Curve 3pool, MIM/3pool, Aave, and Uniswap V3. By exploiting a mispricing in the MachineShare/USDC CurveStableSwapNG pool at 0x32e616f4f17d43f9a5cd9be0e294727187064cb3, the adversary cluster closed the transaction with a net ETH‑denominated profit of approximately 1299.18 WETH while MachineShare/USDC LPs incurred an approximately 5.11m USDC loss.

The root cause is an anyone-can-take ACT opportunity of MEV/arbitrage type: the MachineShare/USDC CurveStableSwapNG pool’s virtual price significantly overstated the realizable value of MachineShare relative to its stablecoin backing in Curve 3pool and MIM/3pool, enabling a permissionless searcher to sell MachineShare into the mispriced pool using only public entrypoints and a Morpho USDC flash loan. No privileged access, private orderflow, or code-level invariant violation was required.

2. Key Background

MachineShare is a tokenized share asset whose value is intended to track a basket of underlying stablecoin liquidity, and MachineShareOracle provides an on-chain price feed for MachineShare. The MachineShare/USDC pair is listed on a CurveStableSwapNG pool at 0x32e616f4f17d43f9a5cd9be0e294727187064cb3, a Vyper stableswap_ng pool with virtual price and mean-reversion logic that is designed to keep the pool’s pricing aligned with its backing.

The incident involves four main protocol components:

  • Morpho at 0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb, used here only as a flash-loan provider for USDC.
  • MachineShare ERC20 at 0x1e33e98af620f1d563fcd3cfd3c75ace841204ef and MachineShareOracle at 0x9434FeBA9eDc5D0Cedc128F417307f8d9afe8bc0.
  • The MachineShare/USDC CurveStableSwapNG pool at 0x32e616f4f17d43f9a5cd9be0e294727187064cb3.
  • Downstream stablecoin venues: Curve 3pool (0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7) and MIM/3pool (0x5a6a4d54456819380173272a5e8e9b9904bdf41b), plus the Uniswap V3 USDC/WETH pool (0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8) for final WETH settlement.

Pre-incident, the virtual prices of Curve 3pool and MIM/3pool were close to 1 (scaled by 1e18), while the MachineShare/USDC CurveStableSwapNG pool virtual price was slightly above 1. This combination meant that MachineShare was effectively overvalued in the MachineShare/USDC pool relative to the stablecoin markets that ultimately backed it.

The price snapshot report around the incident block shows this clearly:

// Curve virtual prices around the incident (prices_block_24273362.json)
{
  "blocks": {
    "pre": {
      "block": 24273361,
      "values": {
        "CurveStableSwapNG_get_virtual_price": 1006853372363990463,
        "Curve3pool_get_virtual_price":        1039823717008703857,
        "MIM3pool_get_virtual_price":          1017632647666468540
      }
    },
    "post": {
      "block": 24273362,
      "values": {
        "CurveStableSwapNG_get_virtual_price": 625294533287057727,
        "Curve3pool_get_virtual_price":        1039823717008714486,
        "MIM3pool_get_virtual_price":          1052257495219597461
      }
    }
  }
}

Between blocks 24273361 and 24273362, the MachineShare/USDC pool virtual price collapses from approximately 1.00685 to approximately 0.62529, while Curve 3pool and MIM/3pool virtual prices remain near or slightly above 1. This establishes that the MachineShare/USDC pool was initially mispriced relative to its stablecoin backing and then repriced sharply as a result of the attacker’s transaction.

3. Vulnerability Analysis & Root Cause Summary

The core economic invariant is that the MachineShare/USDC CurveStableSwapNG pool virtual price should reflect the realizable value of MachineShare, given that MachineShare is ultimately backed by stablecoin liquidity in Curve 3pool and MIM/3pool. When this invariant holds, selling MachineShare into the pool for USDC does not allow a trader to withdraw significantly more USDC than the backing can support.

Immediately before block 24273362, this invariant was violated: the MachineShare/USDC pool virtual price (~1.00685e18) implied near-par or slightly above-par value for MachineShare in USDC terms, while the underlying stablecoin markets (Curve 3pool and MIM/3pool virtual prices near 1e18) and the pool’s configuration only supported approximately 0.62–0.63 USDC per MachineShare. This created an ACT opportunity where a searcher could buy MachineShare cheaply relative to its quoted value in the MachineShare/USDC pool and then sell it into that pool to withdraw excess USDC.

The root cause is therefore a deterministic, permissionless mispricing in the MachineShare/USDC CurveStableSwapNG pool combined with easily accessible flash liquidity and routing across Morpho, MachineShare, Curve pools, and Uniswap V3. The adversary did not exploit a coding bug, unauthorized privilege, or opaque oracle; instead, the exploit is a one-shot arbitrage of a misconfigured or economically fragile CurveStableSwapNG pool that overvalued MachineShare relative to its backing.

4. Detailed Root Cause Analysis

4.1 Pre-state and setup

In the pre-state (block 24273361), the adversary-related cluster consists of:

  • EOA 0x935bfb495e33f74d2e9735df1da66ace442ede48 (transaction sender).
  • EOA 0xa6c248384c5ddd934b83d0926d2e2a1ddf008387 (primary WETH profit sink).

Pre-state WETH balances for this cluster, from the balance diff artifacts, are:

// Pre-state WETH balances for adversary cluster (balance_diff_prestate.json)
{
  "native_balance_deltas": [
    {
      "address": "0x935bfb495e33f74d2e9735df1da66ace442ede48",
      "before_wei": "693218170671324950",
      "after_wei":  "823136647852247725",
      "delta_wei":  "129918477180922775"
    },
    {
      "address": "0xa6c248384c5ddd934b83d0926d2e2a1ddf008387",
      "before_wei": "686120672169267663",
      "after_wei":  "1299736025059816263668",
      "delta_wei":  "1299049904387646996005"
    }
  ]
}

Summing pre-state balances gives exactly 1.379338842840592613 WETH, and summing post-state balances gives 1300.559161707668511393 WETH. The raw change in WETH holdings for the adversary cluster is therefore:

  • value_before_in_reference_asset = 1.379338842840592613 ETH
  • value_after_in_reference_asset = 1300.559161707668511393 ETH
  • value_delta_in_reference_asset = 1299.179822864827918780 ETH

USDC ERC20 balance diffs show that only Morpho (0x98c2...), the MachineShare/USDC CurveStableSwapNG pool (0x32e6...), Curve 3pool (0xbebc...), and the Uniswap V3 USDC/WETH pool (0x8ad5...) have USDC balance changes; neither 0x935b... nor 0xa6c2... holds USDC before or after the transaction. This supports treating the adversary’s USDC exposure as economically flat across the transaction.

4.2 Invariant and pool-level state changes

The decoded state diff for the seed transaction shows how the MachineShare/USDC CurveStableSwapNG pool state changes during the exploit:

// Selected storage changes for CurveStableSwapNG (decoded_state_diff.json)
{
  "contracts": {
    "0x32e616f4f17d43f9a5cd9be0e294727187064cb3": {
      "name": "CurveStableSwapNG",
      "type": "stableswap_ng_pool",
      "storage_changes": [
        {
          "slot_index": 2,
          "variable": "stored_balances",
          "element_index": 0,
          "pre_int": 5127936124721,
          "post_int": 18962782093
        },
        {
          "slot_index": 17,
          "variable": "admin_balances",
          "element_index": 0,
          "pre_int": 0,
          "post_int": 8750755445
        },
        {
          "slot_index": 18,
          "variable": "admin_balances",
          "element_index": 1,
          "pre_int": 0,
          "post_int": 7955950299714610968362
        },
        {
          "slot_index": 26,
          "variable": "last_prices_packed",
          "element_index": 0,
          "decoded": {
            "pre_last_price":  998971928390438759,
            "pre_ma_price":    998971634483438677,
            "post_last_price": 998971634483438677,
            "post_ma_price":   5834646764195952
          }
        }
      ]
    }
  }
}

Key observations from these changes:

  • The USDC balance of the pool (represented in stored_balances[0] and mirrored by ERC20 balance diffs) drops from 5127936124721 to 18962782093, a decrease of 5108973342628 raw USDC units, i.e., approximately 5.108973342628e6 USDC.
  • admin_balances and the packed price fields update in ways consistent with the pool absorbing MachineShare and losing USDC, then re-pricing its virtual price downward.
  • The last_prices_packed decoded values show the moving average price collapsing sharply (post_ma_price becomes much lower), reflecting that the pool’s internal pricing has adjusted to a new, lower MachineShare valuation.

Together with the virtual price snapshot, this confirms that the attacker’s trades pushed the MachineShare/USDC pool from an overvalued state to a new equilibrium where MachineShare is valued around 0.625 USDC.

4.3 Adversary call sequence and mechanism

Using the cast trace logs and the decoded state diff, the effective high-level call sequence inside transaction 0x5697...651f5 is:

  1. The EOA 0x935b... initiates a call to Morpho at 0xbbbb..., flash-borrowing a large amount of USDC.
  2. The borrowed USDC and pre-positioned MachineShare are approved and routed to the MachineShare/USDC CurveStableSwapNG pool at 0x32e6... via public entrypoints (add_liquidity, exchange, remove_liquidity_one_coin).
  3. The pool trades MachineShare for USDC at the inflated pre-incident virtual price, transferring approximately 5.11m USDC out of the pool while absorbing MachineShare exposure.
  4. The USDC and MachineShare flows are further routed through Curve 3pool and MIM/3pool to rebalance into stablecoins and then into WETH via the Uniswap V3 USDC/WETH pool at 0x8ad5....
  5. The Morpho flash loan is repaid, and the remaining WETH is left with the adversary-related EOAs.

The WETH balance diffs for the relevant addresses confirm this profit realization:

// WETH balance diffs (seed/balance_diff.json)
{
  "native_balance_deltas": [
    {
      "address": "0xa6c248384c5ddd934b83d0926d2e2a1ddf008387",
      "before_wei": "686120672169267663",
      "after_wei":  "1299736025059816263668",
      "delta_wei":  "1299049904387646996005"
    },
    {
      "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "before_wei": "2470611125598751182117806",
      "after_wei":  "2469311945614325037924136",
      "delta_wei":  "-1299179984426144193670"
    },
    {
      "address": "0x935bfb495e33f74d2e9735df1da66ace442ede48",
      "before_wei": "693218170671324950",
      "after_wei":  "823136647852247725",
      "delta_wei":  "129918477180922775"
    }
  ]
}

The WETH contract (0xc02a...) loses approximately 1.29917998442614419367e21 wei, while 0x935b... and 0xa6c2... together gain essentially the same amount, up to tiny rounding differences. This matches the earlier computation of a 1299.179822864827918780 ETH increase in the cluster’s WETH holdings.

4.4 Profit interval and gas costs

Gas usage is not directly recorded in the local artifacts, but the transaction metadata (from tx_metadata.json) provides gas_limit and gasPrice, which allow an upper bound on gas fees:

// Fee upper bound (summarized from tx_metadata.json and analyzer iteration 5)
{
  "gas_limit": "0x902a6a",
  "gasPrice":  "0x20b72db",
  "max_fee_eth": "0.000324112539286702"
}

Using this bound, the net ETH-denominated profit for the adversary cluster is:

  • Raw WETH increase: 1299.179822864827918780 ETH.
  • Max gas cost: 0.000324112539286702 ETH.
  • Net profit interval: [1299.179498752288632078, 1299.179822864827918780] ETH.

This interval is strictly positive and narrow relative to the profit magnitude, so the ACT opportunity can be described deterministically as “profitable by approximately 1299.18 ETH” without ambiguity.

5. Adversary Flow Analysis

The adversary flow comprises a single attacker-crafted, anyone-can-take transaction from the EOA 0x935bfb495e33f74d2e9735df1da66ace442ede48:

  • Transaction: 0x569733b8016ef9418f0b6bde8c14224d9e759e79301499908ecbcd956a0651f5 (Ethereum mainnet block 24273362).
  • Classification: Adversary-crafted ACT arbitrage transaction.
  • Execution environment: Standard EIP‑1559 transaction with sufficient ETH for gas; all calls are to publicly documented entrypoints on Morpho, MachineShare, MachineShareOracle, CurveStableSwapNG, Curve 3pool, MIM/3pool, Aave, and Uniswap V3.

At a high level, the flow is:

  1. Flash loan acquisition: The EOA calls Morpho to obtain a USDC flash loan, bringing a large amount of USDC into the adversary’s control for the duration of the transaction.
  2. Approvals and setup: MachineShare allowances are set so that the CurveStableSwapNG pool at 0x32e6... can transfer MachineShare from the attacker; this is visible in the decoded _allowances mapping change in decoded_state_diff.json.
  3. Mispricing exploitation on CurveStableSwapNG: The attacker adds liquidity and performs exchanges in the MachineShare/USDC pool, selling MachineShare into the pool at the elevated pre-incident virtual price. The pool sends out approximately 5.11m USDC while taking on MachineShare, and its internal pricing variables adjust downward.
  4. Routing through backing pools: The attacker routes the obtained USDC and MachineShare through Curve 3pool and MIM/3pool to reconstitute stablecoin positions consistent with underlying backing, effectively realizing the economic difference between the mispriced MachineShare/USDC pool and the backing pools.
  5. Final WETH settlement and flash loan repayment: The attacker swaps stablecoins for WETH on the Uniswap V3 USDC/WETH pool, repays the Morpho flash loan, and retains the residual WETH profit on EOAs 0x935b... and 0xa6c2....

Pre- and post-state balance diffs show that:

  • The MachineShare/USDC CurveStableSwapNG pool loses 5108973342628 raw USDC units (~5.108973e6 USDC).
  • Curve 3pool and the Uniswap V3 USDC/WETH pool gain USDC, consistent with routing from the mispriced pool into a more correctly priced market.
  • The adversary cluster’s WETH holdings increase by approximately 1299.18 ETH, with no residual USDC balance.

No steps in this flow rely on private ordering or privileged roles. Any unprivileged actor with access to public RPC, pool ABIs, and sufficient capital (or similar flash-loan access) could have constructed and submitted the same transaction.

6. Impact & Losses

The primary economic victim is the MachineShare/USDC CurveStableSwapNG pool at 0x32e616f4f17d43f9a5cd9be0e294727187064cb3 and its LPs, who collectively lose approximately 5.11m USDC.

The ERC20 balance diffs for USDC around the seed transaction show:

// USDC pool loss (seed/balance_diff.json)
{
  "erc20_balance_deltas": [
    {
      "token":  "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "holder": "0x32e616f4f17d43f9a5cd9be0e294727187064cb3",
      "before": "5127936124721",
      "after":  "18962782093",
      "delta":  "-5108973342628"
    }
  ]
}

With USDC using 6 decimals, this corresponds to:

  • 5108973342628 / 1e6 = 5.108973342628e6 USDC leaving the MachineShare/USDC CurveStableSwapNG pool.

At the same time, the adversary cluster realizes a net ETH-denominated profit interval:

  • [1299.179498752288632078, 1299.179822864827918780] ETH, after accounting for at most 0.000324112539286702 ETH in gas costs.

Qualitatively:

  • Victims: MachineShare/USDC CurveStableSwapNG LPs, who are left with a pool that holds more MachineShare and less USDC, and whose virtual price drops from ~1.00685 to ~0.62529.
  • Beneficiaries: The adversary cluster EOAs 0x935b... and 0xa6c2..., which end with approximately 1299.18 ETH more WETH than they started with.
  • Scope: Single-block, single-transaction arbitrage using only public infrastructure and flash loans, making it a canonical ACT opportunity.

7. References

  • Seed transaction and metadata: 0x569733b8016ef9418f0b6bde8c14224d9e759e79301499908ecbcd956a0651f5 (Ethereum mainnet block 24273362), with trace and balance data in artifacts/root_cause/seed/1/0x5697.../.
  • Decoded state diff: artifacts/root_cause/data_collector/iter_3/tx/1/0x5697.../decoded_state_diff.json for MachineShare, CurveStableSwapNG, Curve 3pool, and MIM/3pool storage changes.
  • Virtual price snapshots: artifacts/root_cause/data_collector/iter_4/prices_block_24273362.json for pre and post virtual prices of MachineShare/USDC CurveStableSwapNG, Curve 3pool, and MIM/3pool.
  • Balance diffs and pre-state diffs: artifacts/root_cause/seed/1/0x5697.../balance_diff.json and artifacts/root_cause/data_collector/iter_1/tx/1/0x5697.../balance_diff_prestate.json for WETH and USDC movements.
  • Contract sources: Etherscan getsourcecode responses and local repos under artifacts/root_cause/data_collector/iter_2/contract/1/ for CurveStableSwapNG (0x32e6...) and MachineShareOracle (0x9434...), plus Morpho sources under iter_1/contract/1/0xbbbb.../source.