All incidents

Permissionless Router Drain

Share
Jun 25, 2025 03:44 UTCAttackLoss: Pending manual check3 exploit txWindow: 4m 41s
Estimated Impact
Label
Attack
Exploit Tx
3
Addresses
3
Attack Window
4m 41s
Jun 25, 2025 03:44 UTC → Jun 25, 2025 03:48 UTC

Exploit Transactions

TX 1BSC
0x7708aaedf3d408c47b04d62dac6edd2496637be9cb48852000662d22d2131f44
Jun 25, 2025 03:44 UTCExplorer
TX 2BSC
0xf9025e317ce71bc8c055a511fccf0eb4eafd0b8c613da4d5a8e05e139966d6ff
Jun 25, 2025 03:45 UTCExplorer
TX 3BSC
0x8c026c3939f7e2d0376d13e30859fa918a5a567348ca1329836df88bef30c73e
Jun 25, 2025 03:48 UTCExplorer

Victim Addresses

0xb5cb0555c0c51e603ead62c6437da65372e4e1b0BSC
0xb5cb0555a1d28c9dfdbc14017dae131d5c1cc19cBSC
0xb5cb0555c4a333543dbe0b219923c7b3e9d84a87BSC

Similar Incidents

Root Cause Analysis

Permissionless Router Drain

1. Incident Overview TL;DR

On BSC, three adversary-crafted transactions exploited the B5CB helper/router system to drain token balances from source contracts 0xb5cb0555c0c51e603ead62c6437da65372e4e1b0 and 0xb5cb0555a1d28c9dfdbc14017dae131d5c1cc19c. The sender cluster centered on EOA 0xd5c6f3b71bcceb2ef8332bd8225f5f39e56a122c and used freshly deployed helper contracts to call router 0xb5cb0555c4a333543dbe0b219923c7b3e9d84a87, which then executed privileged drain selector 0x0243f5a2 on the source contracts.

The root cause is an access-control failure across two contracts. Router selector 0x94655f2b was callable by an unrelated EOA at pre-state block 52052492, while both source contracts still stored an authorization bit for the router. That combination let any unprivileged caller route a drain payload through the router and transfer listed assets to an arbitrary recipient even though a direct caller was not authorized on the source contracts.

2. Key Background

The affected system is a small family of unverified helper-style contracts on BSC. The two drained source contracts and the router share the same controller constant 0x3801410dcea87efa2141ecc866ecad5e020028dc and the same controller-or-mapping authorization pattern. The source contracts expose drain selector 0x0243f5a2, while the router exposes selector 0x94655f2b, which packages arrays of targets and raw subcalls.

Collector evidence shows that the source contracts do not allow arbitrary callers to invoke selector 0x0243f5a2. In the pre-seed replay, direct calls from the observed attacker EOA revert with _!_. The same evidence also shows that the router was already authorized inside both source contracts through storage slot 0xf67c83c47782efdccd49b3d84f0499c130ebbd12804c0e45b3431c05b19ed74f, which held value 0x1 at the relevant pre-state.

The attacker-side seed helpers were not the root cause. They were disposable wrappers that called the router. The exploitability came from a permissionless protocol path that any unrelated EOA could use.

3. Vulnerability Analysis & Root Cause Summary

This incident is an ATTACK-category ACT opportunity caused by broken privilege composition, not by a private key leak or privileged attacker access. The vulnerable surface spans router 0xb5cb0555c4a333543dbe0b219923c7b3e9d84a87 and source contracts 0xb5cb0555c0c51e603ead62c6437da65372e4e1b0 and 0xb5cb0555a1d28c9dfdbc14017dae131d5c1cc19c.

The intended invariant is straightforward: only controller 0x3801410dcea87efa2141ecc866ecad5e020028dc or deliberately authorized internal operators should be able to trigger selector 0x0243f5a2 and move listed assets out of the source contracts. That invariant broke because the router remained authorized in the source-contract auth mapping while router selector 0x94655f2b accepted arbitrary caller-supplied subcalls.

The critical breakpoint is the router-to-source hop. The source contracts compare msg.sender against the hard-coded controller, fall back to the auth mapping when that check fails, and accept the router because mapping[router] == 1. Since the router itself did not gate selector 0x94655f2b, an unrelated caller could package a valid 0x0243f5a2 payload and cause the router to execute the drain on its behalf.

4. Detailed Root Cause Analysis

The ACT pre-state is BSC block 52052492, immediately before the first observed drain. At that point, both source contracts still authorized router 0xb5cb0555c4a333543dbe0b219923c7b3e9d84a87.

From the authorization proof:

{
  "source": "0xb5cb0555c0c51e603ead62c6437da65372e4e1b0",
  "auth_slot_value_pre_seed": "0x1",
  "router_eth_call_pre_seed": "success",
  "d5_eth_call_pre_seed": "revert _!_"
}

The same artifact records the traced authorization path for 0xb5cb0555a1d28c9dfdbc14017dae131d5c1cc19c: the controller equality check fails, the contract falls back to mapping[caller], and the SLOAD of the router auth slot returns 0x1. This is the concrete code-level permission mechanism that the exploit relies on.

Separately, the router access-classification replay shows selector 0x94655f2b is effectively permissionless in the tested state:

{
  "selector": "0x94655f2b",
  "senders_tested": [
    "0x3801410dcea87efa2141ecc866ecad5e020028dc",
    "0xc269cd69cccb1bbedb44f93c612905219f424c11",
    "0x000000000000000000000000000000000000dead"
  ],
  "conclusion": "All three tested senders, including unrelated EOA 0x000...dead, execute 0x94655f2b successfully at the pre-seed block."
}

That removes any claim that the exploit required attacker-specific privileges. The router call path was open to an arbitrary EOA.

The payload-decoding artifact shows what 0x94655f2b forwards. The first subcall is a direct 0x0243f5a2 drain payload containing a token address, amount, recipient, and a repeated trailing control blob:

selector 0x94655f2b
  target[0] = 0xb5cb0555c0c51e603ead62c6437da65372e4e1b0
  subcall[0] = 0x0243f5a2(fd5840cd..., 1630935807678191, recipient, trailing_blob)

Observed transaction traces match that model. In seed transaction 0x7708aaedf3d408c47b04d62dac6edd2496637be9cb48852000662d22d2131f44, the router called source contract 0xb5cb0555c0c51e603ead62c6437da65372e4e1b0 four times with selector 0x0243f5a2, draining vUSDT, vUSDC, vETH, and vBTC to 0xd5c6f3b71bcceb2ef8332bd8225f5f39e56a122c. In seed transaction 0xf9025e317ce71bc8c055a511fccf0eb4eafd0b8c613da4d5a8e05e139966d6ff, the same pattern drained vBNB, KOGE, CAKE, and BUSD. In seed transaction 0x8c026c3939f7e2d0376d13e30859fa918a5a567348ca1329836df88bef30c73e, the router repeated the pattern against source contract 0xb5cb0555a1d28c9dfdbc14017dae131d5c1cc19c.

The exploit remained live until the controller removed the router authorization bit. The provenance-window artifact shows that mapping[router] stayed set through blocks 52057416 for e1b0 and 52057680 for c19c, then was cleared by direct controller calls to selector 0x268a066f(router) in transactions 0x8e7e1960fcf7fdff7b382ee736c1e45eacc79182b006bbe9fb9153b5884b7c77 and 0x36a9d6bdbe090a75cbc92a1babc2fa27a962ab933878b8050a26d3813a44b8bf.

5. Adversary Flow Analysis

The observed adversary flow is short and deterministic.

  1. The adversary EOA deploys a bespoke helper contract in the same transaction.
  2. That helper calls router 0xb5cb0555c4a333543dbe0b219923c7b3e9d84a87 with selector 0x94655f2b.
  3. The router decodes the attacker-supplied target/subcall arrays and performs direct CALLs into the source contract’s selector 0x0243f5a2.
  4. The source contract evaluates msg.sender == router, falls back to the auth mapping, sees mapping[router] == 1, and executes the transfer.
  5. The listed asset balance moves from the source contract to the adversary-chosen recipient.

Representative boundary-call evidence from the first seed transaction:

{
  "from": "0xb5cb0555c4a333543dbe0b219923c7b3e9d84a87",
  "to": "0xb5cb0555c0c51e603ead62c6437da65372e4e1b0",
  "selector": "0x0243f5a2",
  "token_label": "vUSDT",
  "amount_dec": "1630935807678191",
  "recipient": "0xd5c6f3b71bcceb2ef8332bd8225f5f39e56a122c"
}

The three exploit transactions are:

  • 0x7708aaedf3d408c47b04d62dac6edd2496637be9cb48852000662d22d2131f44
  • 0xf9025e317ce71bc8c055a511fccf0eb4eafd0b8c613da4d5a8e05e139966d6ff
  • 0x8c026c3939f7e2d0376d13e30859fa918a5a567348ca1329836df88bef30c73e

All three are adversary-crafted transactions realizable by any unprivileged EOA while the same preconditions hold: router auth bit still set, target source still funded, and caller able to submit a 0x94655f2b payload.

6. Impact & Losses

The impact is unauthorized extraction of listed balances from two source contracts into an adversary-chosen recipient. The observed incident drained multiple Venus vTokens and spot tokens, including vUSDT, vUSDC, vETH, vBTC, vBNB, KOGE, CAKE, BUSD, and additional assets from the second source contract as summarized in the root-cause artifact.

The collector evidence deterministically proves the drain mechanism and per-call transferred amounts, but the session’s root-cause artifact does not provide a complete normalized aggregate loss table with decimals across every affected token. For that reason, the metadata keeps loss empty rather than inferring a partial total.

7. References

  1. Seed exploit tx 0x7708aaedf3d408c47b04d62dac6edd2496637be9cb48852000662d22d2131f44
  2. Seed exploit tx 0xf9025e317ce71bc8c055a511fccf0eb4eafd0b8c613da4d5a8e05e139966d6ff
  3. Seed exploit tx 0x8c026c3939f7e2d0376d13e30859fa918a5a567348ca1329836df88bef30c73e
  4. Authorization proof for router-to-source mapping bit and direct-call revert behavior
  5. Router selector 0x94655f2b access classification replay
  6. Router payload decode showing nested 0x0243f5a2 drain calls
  7. Boundary-call extraction for the observed seed sweeps
  8. Controller deauthorization transactions 0x8e7e1960fcf7fdff7b382ee736c1e45eacc79182b006bbe9fb9153b5884b7c77 and 0x36a9d6bdbe090a75cbc92a1babc2fa27a962ab933878b8050a26d3813a44b8bf