Calculated from recorded token losses using historical USD prices at the incident time.
0xc8d7899f22bc4995c8176e3f2a5ba3f5e87d95e5Ethereum0x13ebe7f59e87fe12850c26eaf27812736104d3f9Ethereum0x3e992b0dfb1aa0add70543ed0d13262c136fe6b3EthereumTransit Swap exposed a public Ethereum proxy entry that let arbitrary callers forward attacker-chosen claim payloads into a privileged token-claim path. In exploit transaction 0xba75ad7a43e784f51fe777d749fc55ae10f1df2bcb01cde97641613b19acb6ec, and again in follow-up drain transactions, the attacker cluster reused victims' standing token approvals to Transit's spender contract and pulled funds directly to an attacker-controlled recipient.
The root cause is an authorization failure at the first public entry point. The public selector 0x006de4df on 0xc8d7899f22bc4995c8176e3f2a5ba3f5e87d95e5 forwarded attacker-controlled victim, recipient, token, and amount data into 0x13ebe7f59e87fe12850c26eaf27812736104d3f9 and then 0x3e992b0dfb1aa0add70543ed0d13262c136fe6b3 without binding those parameters to msg.sender.
The relevant Transit stack on Ethereum is the public proxy 0xc8d7899f22bc4995c8176e3f2a5ba3f5e87d95e5, bridge proxy 0x13ebe7f59e87fe12850c26eaf27812736104d3f9, claim spender 0x3e992b0dfb1aa0add70543ed0d13262c136fe6b3, and fee helper 0x94ba99f5fd1ee8ac5c1ebd15155019ce54af47b4. Collector provenance shows these protocol contracts were deployed by 0xfab745c5ee6c59c09605a40464232930892ba48c well before the October 2022 exploit window, while attacker helper 0x17ff6c94ba3a49c72ef2f10782de8a6152f204ea was deployed by 0x5f0b31aa37bce387a8b21554a8360c6b8698fbef only minutes before the exploit burst.
0xc261e210930f700f7ba1cb9ad5c166bdfee3046cdd7152b49f3de1ca529d1d48Normal Transit users had previously approved USDT to 0x3e992b0dfb1aa0add70543ed0d13262c136fe6b3. The pre-exploit allowance snapshot at block 15655117 shows multiple sampled victims still had uint256.max allowance to that spender, including victim 0x30c22d6d866aa7402cec1d659e2d4fce1b7a89bd.
Legitimate user traffic and attacker traffic both reached the same public proxy selector. A prior legitimate user trace 0x5bf4709bb4b284c7512430e4989f2d0dfb8ac5140a8e79a81807e2c6594191f3 demonstrates that Transit intended 0x006de4df to be publicly callable, which makes caller-side authorization at that boundary critical.
This is an ATTACK-class ACT opportunity caused by broken authorization at the proxy layer. The downstream claim spender was not independently open to arbitrary callers: the bridge proxy and spender both relied on the upstream Transit proxy to enforce who was allowed to submit claim semantics. That trust boundary failed because the public 0x006de4df entry accepted attacker-controlled payloads and forwarded them into the trusted internal path unchanged.
The security invariant was straightforward: only the user who granted allowance, or an authorized workflow acting on that user's intended settlement, should be able to cause 0x3e992b... to execute transferFrom against that user's balance. The first code-level breakpoint was the public entry on 0xc8d7899..., which did not verify that the embedded victim and recipient parameters matched an authorized caller context before dispatching into 0x13ebe7... and 0x3e992b....
Once that proxy hop succeeded, the rest of the exploit followed intended protocol behavior. The spender contract consumed a valid pre-existing allowance and transferred approved tokens from the victim address to an attacker-controlled recipient. The protocol therefore did not fail because USDT approvals were missing or forged; it failed because a public dispatcher exposed privileged claim rights to any caller.
The collector artifacts show three critical facts that close the root cause deterministically. First, sampled victims had active approvals to 0x3e992b... immediately before the exploit window. Second, the exploit path traversed the same public Transit selector used by legitimate users. Third, exploit execution ended in direct ERC-20 transferFrom calls from victims to the attacker cash-out address.
The exploit receipt for 0xba75ad7a... contains repeated USDT Transfer events from victim addresses to 0x75f2aba6a44580d7be2c4e42885d4a1917bffd46, including:
USDT Transfer:
from 0x30c22d6d866aa7402cec1d659e2d4fce1b7a89bd
to 0x75f2aba6a44580d7be2c4e42885d4a1917bffd46
value 0x02625a00
The validator reran the ACT path on a mainnet fork with a fresh attacker address and observed the exact semantic call chain:
TransitProxy::0x006de4df(...)
-> TransitBridgeProxy::callBytes(...)
-> TransitClaimSpender::claimTokens(USDT, victim, attacker, 40000000)
-> USDT::transferFrom(victim, attacker, 40000000)
That reproduction is important because it removes dependence on the observed attacker helper and proves the issue is not tied to privileged attacker artifacts. The fresh attacker address simply called the public Transit proxy entry and received 40 USDT from the sampled victim, exactly as the oracle definition required.
The collector's semantic decode of 0x006de4df explains why this worked. The public proxy accepted payloads embedding application-channel data plus a downstream 0x0a5ea466 claimTokens(address,address,address,uint256) call carrying token, victim, recipient, and amount semantics. The same artifact also notes that the public proxy bytecode contains whitelist and reentrancy logic but no top-level caller-equality check before constructing the privileged downstream call. That is the missing authorization control that made the exploit permissionless.
The attacker lifecycle began with preparation. EOA 0x5f0b31aa37bce387a8b21554a8360c6b8698fbef deployed helper contract 0x17ff6c94ba3a49c72ef2f10782de8a6152f204ea in transaction 0x36b71a0f6a7ea0286befb20621191e22b750aebc8702af17e5bfb5af92e1a628 at block 15655094.
The exploit stage followed in a burst of transactions including 0xba75ad7a43e784f51fe777d749fc55ae10f1df2bcb01cde97641613b19acb6ec, 0x19d45550a6d55128bad90d0f78f048bb9681b468c3a898dee210965130bdfa8d, and 0xc261e210930f700f7ba1cb9ad5c166bdfee3046cdd7152b49f3de1ca529d1d48. In each case, the attacker supplied payloads that targeted approved victims and directed the stolen tokens to 0x75f2aba6a44580d7be2c4e42885d4a1917bffd46. The exploit candidate summary shows that these transactions moved at least millions of USDT to the adversary cluster.
Cash-out followed immediately. Root-cause evidence ties 0x75f2... to swaps through SwapRouter02 and later bridging through AnyswapV6Router, which is consistent with a completed exploit lifecycle rather than a failed probe.
Collector-observed exploit-window losses include:
[
{ "token_symbol": "USDT", "amount": "6091215710710", "decimal": 6 },
{ "token_symbol": "USDC", "amount": "743004179864", "decimal": 6 },
{ "token_symbol": "DAI", "amount": "67709896489136770000000", "decimal": 18 }
]
These amounts correspond to at least 6,091,215.710710 USDT, 743,004.179864 USDC, and 67,709.89648913677 DAI drained during the recovered exploit window. The protocol impact was broader than those observed totals because any user who still had live approvals to 0x3e992b... and held approved balances remained exposed to the same unauthorized claim path.
The validation and report are supported by the following evidence set:
0xba75ad7a43e784f51fe777d749fc55ae10f1df2bcb01cde97641613b19acb6ec, 0x19d45550a6d55128bad90d0f78f048bb9681b468c3a898dee210965130bdfa8d, 0xc261e210930f700f7ba1cb9ad5c166bdfee3046cdd7152b49f3de1ca529d1d48.0x5bf4709bb4b284c7512430e4989f2d0dfb8ac5140a8e79a81807e2c6594191f3.0xc8d7899f22bc4995c8176e3f2a5ba3f5e87d95e5, 0x13ebe7f59e87fe12850c26eaf27812736104d3f9, 0x3e992b0dfb1aa0add70543ed0d13262c136fe6b3, 0x94ba99f5fd1ee8ac5c1ebd15155019ce54af47b4./workspace/session/artifacts/validator/forge-test.log, which independently reproduced the unauthorized claim path from a fresh attacker address.