# Rubic proxy: arbitrary external call drains user USDC approvals

Rubic proxy's routerCallNative made arbitrary external calls, letting an attacker transferFrom USDC from 26 users who had approved the proxy, stealing $1.5M.

- Payout: Real-world hack
- Severity: critical
- Program: - Rubic
- Analysis by: DeFiHackLabs
- Disclosed: 2022-12-25
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2022-12/Rubic_exp.sol
- Library page: http://bugbountylibrary.com/r/dhl%3A20221225-rubic
- Tags: area:web3 domain:web3 impact:data-leak impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Rubic cross-chain proxy contracts (routerCallNative) on Ethereum mainnet
**Root cause:** routerCallNative accepted attacker-controlled calldata and executed it as an external call from the proxy, without restricting the target or function. Since victims had approved the proxy to spend USDC, the attacker could invoke USDC.transferFrom on their behalf.
**Steps:**
1. Identify victims who granted USDC allowance to Rubic proxy 0x3335A88bb18fD3b6824b59Af62b50CE494143333 or 0x33388CF69e032C6f60A420b37E44b1F5443d3333.
2. Build BaseCrossChainParams with router set to USDC (0xA0b8...eB48) and integrator set to 0x677d6EC74fA352D4Ef9B1886F6155384aCD70D90.
3. Craft calldata `transferFrom(victim, attacker, amount)` where amount = min(balance, allowance).
4. Call `Rubic1.routerCallNative(_params1, data)` (or `Rubic2.routerCallNative("", _params2, data)`) for each victim.
5. Repeat across 26 victims to drain approved USDC to the attacker contract.
**Exploitation:** The attacker called the Rubic proxy's routerCallNative with router=USDC and calldata encoding transferFrom(victim, attacker, amount). The proxy executed the call, pulling USDC from each victim's allowance to the attacker. 26 victims were drained for ~$1.5M.
**Insight:** Cross-chain router/proxy contracts that take arbitrary calldata and execute it are effectively a universal approval spender: any token allowance to the proxy can be pulled by anyone. Check whether routerCallNative validates the router/target and selector, and enumerate users with outstanding allowances to such proxies.

