Treasury allowance-router abuse drains USDC/USDT/WBTC cross-chain
Exploit Transactions
0xc15df1d131e98d24aa0f107a67e33e66cf2ea27903338cc437a3665b6404dd570x35540e9efa62c63952715c7a07fccc396311b2f6c2c159bd0c8c81620fc96d150x8f28a7f604f1b3890c2275eec54cd7deb40935183a856074c0a06e4b5f72f25aVictim Addresses
0xba15e9b644685cb845af18a738abd40c6bcd78edBase0xf9A88E0E6152C1b403B8B162E1790D96e08d201fBSC0x5240B03Be5Bc101A0082074666dd89aD883e1f9dEthereumLoss Breakdown
Similar Incidents
Base USDC drain from malicious transferFrom spender approvals
34%USDC drain via unchecked Uniswap V3-style callback
33%SynapLogicErc20 Router Flash-Loan Over-Mint Exploit
32%Odos router signature-validation bug enables arbitrary token drains
31%TSURUWrapper onERC1155Received bug mints unbacked tokens and drains WETH
30%GPv2Settlement allowance leak lets router drain WETH and USDC
30%Root Cause Analysis
Treasury allowance-router abuse drains USDC/USDT/WBTC cross-chain
1. Incident Overview TL;DR
Across Base, BSC, and Ethereum, an adversary cluster of fresh EOAs and helper contracts abused public router entrypoints that already held large token allowances from three treasury-style holders. In one attacker-crafted transaction per chain, these routers executed transferFrom calls that pulled USDC, USDT, and WBTC out of the treasuries and into attacker-controlled EOAs or LP positions. The core root cause is architectural: routers that were approved as spenders for large treasury token balances exposed public entrypoints that allowed arbitrary EOAs to trigger transferFrom from those treasuries without enforcing any treasury-owner or governance authorization, violating a basic treasury-spend invariant.
2. Key Background
The affected flows involve three independent treasuries and their tokens:
- Base: FiatTokenV2_2 USDC held by
0xba15e9b644685cb845af18a738abd40c6bcd78ed, with large allowances granted to routers0x616000e384Ef1C2B52f5f3A88D57a3B64F23757eand0xdC3914cA7b18A2BF41B43A263258B71e32296D7D. - BSC: BEP20USDT held by
0xf9A88E0E6152C1b403B8B162E1790D96e08d201f, with a large allowance to router0x353713e18f997494D00Dd80aCD350759A5e726A2. - Ethereum: WBTC held by
0x5240B03Be5Bc101A0082074666dd89aD883e1f9d, with an effectively infinite allowance to router0xD83d960deBEC397fB149b51F8F37DD3B5CFA8913.
All three tokens implement standard ERC20/BEP20-style approval and transferFrom semantics. For example, the Base USDC implementation is a FiatTokenV2_2 contract compiled from the Circle USDC codebase:
// Collected USDC implementation for Base (FiatTokenV2_2)
// Origin: verified source for token 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
contract FiatTokenV2_2 is FiatTokenV2_1 {
// ...
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
bytes memory signature
) external whenNotPaused {
_permit(owner, spender, value, deadline, signature);
}
// standard ERC20 allowance / transferFrom semantics are inherited from FiatTokenV1/V2
}
On BSC, BEP20USDT exposes the usual ERC20-compatible interface, including allowance, approve, and transferFrom:
// Collected BEP20USDT interface (BSC)
interface IBEP20 {
function totalSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address _owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}
Ethereum WBTC uses the standard OpenZeppelin-style ERC20 implementation with allowance and transferFrom, as seen in the collected source under seed/1/0x2260fa.../src/Contract.sol. In all three cases, any contract holding sufficient allowance can invoke transferFrom(holder, recipient, amount) without additional on-chain authorization checks.
Routers on each chain are long-lived public contracts:
- Base routers:
0x616000e384Ef1C2B52f5f3A88D57a3B64F23757eand0xdC3914cA7b18A2BF41B43A263258B71e32296D7D(aggregator-style routers that hold a2^256-1USDC allowance from the Base treasury holder). - BSC router:
0x353713e18f997494D00Dd80aCD350759A5e726A2(aggregator/router used for USDT routing on BSC). - Ethereum router:
0xD83d960deBEC397fB149b51F8F37DD3B5CFA8913(router that holds an infinite WBTC allowance from the WBTC treasury holder and routes into Uniswap V3).
Disassembly for these routers (under artifacts/root_cause/data_collector/iter_2/contract/.../cast_disassemble.txt) shows aggregator-style entrypoints that interpret calldata and ultimately issue ERC20 transferFrom calls using the router’s allowances. For example, the Ethereum router runtime bytecode clearly embeds the WBTC address and the ERC20 transferFrom selector:
// Extract from runtime_bytecode.json for router 0xD83d96... (Ethereum)
{
"result": "0x6101e0...12261ee7...6377633a...70a08231...23b872dd...000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe88..."
}
The adversary operates under an Anyone-Can-Take (ACT) model: any unprivileged EOA that knows about these allowances and router entrypoints can deploy a helper contract and send the same calldata to realize the same transferFrom-based treasury spends, without any special keys, whitelists, or private orderflow.
3. Vulnerability Analysis & Root Cause Summary
The incident is classified as an ACT-style attack. The vulnerability is architectural: public routers with very large treasury token allowances can perform transferFrom-based spends from treasury holders without binding those spends to any governance-controlled or treasury-operations-only caller.
Invariant (treasury-spend safety). For each treasury holder H and ERC20 token T, any on-chain debit T.transferFrom(H, X, amount) that spends treasury funds must be initiated only by an authorized governance or treasury-operations component and must not be triggerable by arbitrary EOAs solely via pre-granted allowances.
Breakpoint (violating call path). In the router entrypoints used on Base, BSC, and Ethereum, the contracts call token.transferFrom(holder, recipient, amount) using the router’s allowance from the treasury holder, without checking that msg.sender is an authorized treasury operator or that the holder address matches msg.sender. Once a large allowance is granted, any EOA can deploy a helper and invoke these entrypoints to route arbitrary treasury spends to attacker-controlled recipients.
The root cause is therefore the combination of:
- Treasury holders granting large or
2^256-1allowances to public routers. - Router implementations that expose generic, publicly callable entrypoints for routing/swapping that internally perform
transferFromfrom these treasuries solely based on allowance. - Lack of additional authorization logic that binds treasury spends to governance or admin call paths.
Helper contracts deployed by the adversary (0xcCE2..., 0xDE59..., 0x5c9288...) simply exploit this design; they are not the root cause themselves. They forward calls into the routers with carefully crafted calldata that causes the routers to spend from the treasuries.
4. Detailed Root Cause Analysis
4.1 Pre-state and ACT opportunity
At the ACT opportunity block heights
- Base: block
41289841(tx0xc15df1d1...), - BSC: block
77381400(tx0x35540e9e...), - Ethereum: block
24313234(tx0x8f28a7f6...),
the following facts hold and are fixed on-chain:
- Treasury holders:
- Base USDC holder:
0xba15e9b644685cb845af18a738abd40c6bcd78ed. - BSC USDT holder:
0xf9A88E0E6152C1b403B8B162E1790D96e08d201f. - Ethereum WBTC holder:
0x5240B03Be5Bc101A0082074666dd89aD883e1f9d.
- Base USDC holder:
- Token implementations:
- Base USDC: FiatTokenV2_2 deployed at layout address
0x2ce6311ddae708829bc0784c967b7d77d19fd779, token address0x833589fcd6edb6e08f4c7c32d4f71b54bda02913. - BSC USDT: BEP20USDT at
0x55d398326f99059ff775485246999027b3197955. - Ethereum WBTC: WBTC at
0x2260fac5e5542a773aa44fbcfedf7c193bc2c599.
- Base USDC: FiatTokenV2_2 deployed at layout address
- Routers:
- Base:
0x616000e384Ef1C2B52f5f3A88D57a3B64F23757eand0xdC3914cA7b18A2BF41B43A263258B71e32296D7D. - BSC:
0x353713e18f997494D00Dd80aCD350759A5e726A2. - Ethereum:
0xD83d960deBEC397fB149b51F8F37DD3B5CFA8913.
- Base:
Approval and authorization logs collected in artifacts/root_cause/data_collector/iter_3/contract/*/logs/approval_permit_* show that, prior to the attacker-crafted profit transactions, each treasury holder has given the corresponding router a very large allowance:
- Base USDC: an allowance of
2^256-1from0xba15...to router0x6160.... - BSC USDT: a very large allowance from
0xf9A8...to router0x3537.... - Ethereum WBTC: an effectively infinite allowance from
0x5240...to router0xD83d96....
These allowances create a standing capability for the routers to call transferFrom against the treasury holders. Since routers are publicly callable, any EOA that knows the function selectors and encodings can exercise this capability.
4.2 Router code paths and transferFrom
Disassembly and runtime bytecode for the routers (data_collector iter_2) show aggregator-style entrypoints:
- On Base, selector
0x87395540on routers0x6160.../0xdC39...parses calldata describing token routes and invokestransferFromon FiatTokenV2_2 USDC using the router’s allowance from0xba15.... - On BSC, router
0x3537...exposes routing entrypoints that callBEP20USDT.transferFromon token0x55d3...from0xf9A8...to arbitrary recipients. - On Ethereum, router
0xD83d96...exposes selector0x6377633a, which in the seed trace for tx0x8f28a7f6...routes WBTC and PAXG via Uniswap V3, invokingWBTC.transferFrom(0x5240..., helper, 36.91897652 WBTC)based solely on the router’s allowance.
In all three cases, there are no conditional checks tying the spend to a treasury-operator-only caller. msg.sender is simply the attacker helper or EOA that calls the router. The router’s authority to spend treasury funds is bounded only by the allowance, not by caller identity.
4.3 Helper contracts and deploy-and-call pattern
Each chain uses a fresh EOA and helper pair:
- Base:
- EOA
0x6caad74121bf602e71386505a4687f310e0d833e(nonce 0). - Helper
0xcCE2E1a23194bD50d99eB830af580Df0B7e3225b.
- EOA
- BSC:
- EOA
0x4bcd06648a9315a233229b634b89011009f7b195(nonce 0). - Helper
0xDE5957A205008fFfcDDFC44cC01535823dF15b00.
- EOA
- Ethereum:
- EOA
0xe3e73f1e6ace2b27891d41369919e8f57129e8ea(nonce 0). - Helper
0x5c92884dFE0795db5ee095E68414d6aaBf398130.
- EOA
Seed traces for the three attacker transactions show a consistent pattern: contract creation for the helper, followed by an immediate call from the helper into the router, all within a single attacker-crafted transaction:
# Seed transaction trace for Base tx 0xc15df1d1... (excerpt)
# Origin: artifacts/root_cause/seed/8453/0xc15df1d1.../trace.cast.log
depth:1 OPCODE: "CREATE" # helper 0xcCE2... deployed by EOA 0x6caad...
...
depth:2 OPCODE: "CALL" # helper calls router 0x6160... selector 0x87395540
...
depth:3 OPCODE: "CALL" # router calls USDC.transferFrom(0xba15..., 0x6caad..., amount)
The BSC and Ethereum traces under seed/56/.../trace.cast.log and seed/1/.../trace.cast.log show analogous deploy-and-call-router sequences, ending in ERC20 transfer logic.
4.4 Treasury balance deltas and profit realization
Balance diff artifacts confirm concrete token movements.
On Base (USDC), balance_diff.json for tx 0xc15df1d1... shows:
// Seed balance diff for Base USDC tx 0xc15df1d1...
{
"erc20_balance_deltas": [
{
"token": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"holder": "0xba15e9b644685cb845af18a738abd40c6bcd78ed",
"delta": "-13342433169249"
},
{
"token": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"holder": "0x6caad74121bf602e71386505a4687f310e0d833e",
"delta": "13342433169249"
}
]
}
On BSC (USDT), balance_diff.json for tx 0x35540e9e... shows:
// Seed balance diff for BSC USDT tx 0x35540e9e...
{
"erc20_balance_deltas": [
{
"token": "0x55d398326f99059ff775485246999027b3197955",
"holder": "0xf9a88e0e6152c1b403b8b162e1790d96e08d201f",
"delta": "-25791508841389255775657"
},
{
"token": "0x55d398326f99059ff775485246999027b3197955",
"holder": "0x04028e5eaf698f93929e33015ca42b9c5eabd46a",
"delta": "25791508841389255775657"
}
]
}
On Ethereum (WBTC), balance_diff.json for tx 0x8f28a7f6... focuses on native balances, while iter_3 ERC20-focused traces and WBTC Transfer logs show a debit of 36.91897652 WBTC from 0x5240... and a corresponding credit into a Uniswap V3 PAXG/WETH LP position (tokenId 1181114) controlled by helper 0x5c9288....
These deltas match the narrative in root_cause.json, which summarizes the cluster-level profit as:
- Base: +USDC to adversary EOA
0x6caad7...from treasury holder0xba15.... - BSC: +25,791.508841389255775657 USDT to EOA
0x04028e5eAF698F93929E33015ca42b9c5EaBd46afrom treasury holder0xf9A8.... - Ethereum: +36.91897652 WBTC-equivalent routed into a Uniswap V3 LP position controlled by helper
0x5c9288....
Native-balance deltas (ETH/BNB) show only small gas expenditures from the adversary EOAs on each chain (on the order of 10^-3 native units), so the net portfolio change for the adversary cluster is strictly positive across Base, BSC, and Ethereum.
4.5 ACT exploit conditions
The ACT opportunity is fully described in act_opportunity in root_cause.json and is supported by seed/index.json and the iter_* artifacts. For any new adversary:
- Pre-condition 1: Treasury holders grant large or essentially unlimited allowances of their tokens to public routers (
approve(holder -> router, amount)). - Pre-condition 2: Routers expose entrypoints that allow arbitrary
msg.sendervalues to causetransferFrom(holder, recipient, amount)using router-held allowances. - Pre-condition 3: The attacker can deploy a helper contract and send calldata that triggers the same router code path, using only public chain state (allowances, contract bytecode, ABIs, and prior txs).
- Pre-condition 4: There is sufficient AMM or routing liquidity for swaps/LP mints (where applicable) so that the route remains economically profitable.
Given these conditions, any unprivileged EOA can realize the same success predicate as the observed adversary cluster by replaying the pattern (deploy helper, call router entrypoint, consume treasury allowances) without any special access.
5. Adversary Flow Analysis
5.1 Adversary-related cluster accounts
Root_cause.json identifies the minimal adversary-related cluster with explicit reasoning:
- Base:
- EOA
0x6caad74121bf602e71386505a4687f310e0d833e(nonce-0): deploys helper0xcCE2...and receives the USDC outflow from0xba15...in the seed tx. - Helper
0xcCE2E1a23194bD50d99eB830af580Df0B7e3225b: called by the EOA, in turn calls routers0x6160.../0xdC39...to route the treasury USDC allowance into the EOA.
- EOA
- BSC:
- EOA
0x4bcd06648a9315a233229b634b89011009f7b195(nonce-0): deploys helper0xDE59...and pays gas for the BSC exploit tx. - Helper
0xDE5957A205008fFfcDDFC44cC01535823dF15b00: calls router0x3537...to move approximately 25,791.5088 USDT from treasury holder0xf9A8...to profit EOA0x04028.... - Profit EOA
0x04028e5eAF698F93929E33015ca42b9c5EaBd46a: receives the USDT outflow from the BSC treasury holder.
- EOA
- Ethereum:
- EOA
0xe3e73f1e6ace2b27891d41369919e8f57129e8ea(nonce-0): deploys helper0x5c9288..., originates the seed tx, and pays gas; ultimately controls the Uniswap V3 LP position funded by stolen WBTC. - Helper
0x5c92884dFE0795db5ee095E68414d6aaBf398130: receives WBTC via router0xD83d96...and mints a Uniswap V3 PAXG/WETH position (tokenId1181114) holding the WBTC-equivalent value.
- EOA
Victim candidates are:
- Base USDC treasury holder:
0xba15e9b644685cb845af18a738abd40c6bcd78ed(labeling not externally verified in this dataset). - BSC USDT treasury holder:
0xf9A88E0E6152C1b403B8B162E1790D96e08d201f. - Ethereum WBTC treasury holder:
0x5240B03Be5Bc101A0082074666dd89aD883e1f9d.
These accounts are supported by the seed metadata and data_collector address-activity windows, which show the treasuries’ approval history and the adversary EOAs’ fresh nonce patterns.
5.2 Lifecycle stages
Root_cause.json decomposes the adversary flow into three stages, all of which can be reproduced by any unprivileged EOA with the same pre-state.
Stage 1: Pre-existing treasury approvals to public routers.
- Historical approvals from:
0xba15...→0x6160...(Base USDC).0xf9A8...→0x3537...(BSC USDT).0x5240...→0xD83d96...(Ethereum WBTC).
- Evidence: Approval/permit logs under
artifacts/root_cause/data_collector/iter_3/contract/*/logs/approval_permit_*show allowances at2^256-1or similarly large values at or before the exploit blocks.
Stage 2: Adversary helper deployment and setup.
- Base: tx
0xc15df1d1...at block41289841(chainid 8453) – EOA0x6caad...deploys helper0xcCE2...and helper immediately calls routers0x6160.../0xdC39.... - BSC: tx
0x35540e9e...at block77381400(chainid 56) – EOA0x4bcd...deploys helper0xDE59...and calls router0x3537.... - Ethereum: tx
0x8f28a7f6...at block24313234(chainid 1) – EOA0xe3e7...deploys helper0x5c9288...and calls router0xD83d96...(selector0x6377633a). - Evidence: seed traces (
trace.cast.log) for each tx show contract creation followed by router calls from the helpers within a single transaction.
Stage 3: Treasury spends and profit realization.
- Base: routers invoke
USDC.transferFrom(0xba15..., 0x6caad..., amount)using the pre-existing allowance, debiting the treasury and crediting the adversary EOA. - BSC: router invokes
BEP20USDT.transferFrom(0xf9A8..., 0x04028..., amount)to move the USDT balance to the adversary. - Ethereum: router invokes
WBTC.transferFrom(0x5240..., 0x5c9288..., 36.91897652 WBTC), after which the helper mints a Uniswap V3 PAXG/WETH position (tokenId1181114) holding the WBTC-equivalent value. - Evidence: balance diffs under
artifacts/root_cause/seed/*/balance_diff.jsonand WBTC transfer logs/Uniswap V3 position logs indata_collector/iter_3show debits from the treasury holders and credits to adversary-controlled addresses or LP positions.
Throughout all stages, there are no privileged roles, admin keys, or whitelists involved in the attacker-crafted transactions; they rely purely on public allowances and router code.
6. Impact & Losses
The impact is fully captured in token-level balance deltas across the three chains:
- Base (USDC):
- Holder
0xba15e9b644685cb845af18a738abd40c6bcd78edloses USDC (delta-13342433169249in token units) to adversary EOA0x6caad74121bf602e71386505a4687f310e0d833e. - EOA
0x6caad7...gains the same amount, funded entirely by the treasury holder via router0x6160....
- Holder
- BSC (USDT):
- Holder
0xf9A88E0E6152C1b403B8B162E1790D96e08d201floses25,791.508841389255775657USDT (delta-25791508841389255775657units). - EOA
0x04028e5eAF698F93929E33015ca42b9c5EaBd46agains the same USDT amount.
- Holder
- Ethereum (WBTC):
- Holder
0x5240B03Be5Bc101A0082074666dd89aD883e1f9dloses36.91897652WBTC, which is routed into a Uniswap V3 LP position (tokenId1181114) whose owner is helper0x5c9288...controlled by the adversary EOA.
- Holder
Across all chains, treasury-style holders lose control of significant USDC, USDT, and WBTC balances to an unprivileged adversary cluster. Because the mechanism only depends on public allowances and router behavior, the same pattern can be repeated by any other attacker as long as similar router allowances remain in place.
7. References
This analysis and root cause conclusion are supported by the following on-chain artifacts and code:
- Seed transaction metadata, traces, and balance diffs for the three attacker-crafted transactions:
- Base:
artifacts/root_cause/seed/8453/0xc15df1d1.../{metadata.json,balance_diff.json,trace.cast.log}. - BSC:
artifacts/root_cause/seed/56/0x35540e9e.../{metadata.json,balance_diff.json,trace.cast.log}. - Ethereum:
artifacts/root_cause/seed/1/0x8f28a7f6.../{metadata.json,balance_diff.json,trace.cast.log}.
- Base:
- Collected token source code:
- Base USDC (FiatTokenV2_2): `artifacts/root_cause/seed/8453/0x2ce6311d.../src<REDACTED_LOCAL_PATH>
- BSC BEP20USDT and WBNB:
artifacts/root_cause/seed/56/0x55d39832.../src/Contract.sol,seed/56/0xbb4cdb9c.... - Ethereum WBTC and WETH9:
artifacts/root_cause/seed/1/0x2260fac5.../src/Contract.sol,seed/1/0xc02aaa39....
- Router and helper bytecode/disassembly and address-activity windows:
artifacts/root_cause/data_collector/iter_2/contract/*/{runtime_bytecode.json,cast_disassemble.txt}.artifacts/root_cause/data_collector/iter_2/address/*/txlist_normal.jsonfor treasury holders, routers, and profit EOAs.
- Allowance history and position lifecycle logs:
- Approval and permit logs:
artifacts/root_cause/data_collector/iter_3/contract/*/logs/approval_permit_*. - Uniswap V3 position logs:
artifacts/root_cause/data_collector/iter_3/contract/1/0xc36442b4.../logs/position_lifecycle_tokenId_1181114.json.
- Approval and permit logs:
Together, these artifacts provide a deterministic, reproducible evidence trail for the ACT opportunity, the adversary cluster, the invariant violation, and the realized losses.