Full Report
O3 is a multi-service DeFi project with bridging solutions for 10+ chains. It functions as a fairly classic bridge: send tokens to bridge contract on chain A, then a mint the representation on chain B. In the ecosystem, the aggregators is a role that attempts to find the cheapest path going from the source currency to the target currency when sending funds out to the bridge or retrieving them on the other side. There are various aggregators for crosschain swaps, same chain swaps and more. In all of the functions, callers are required to approve() the source tokens aggregator contract so they can pull them to perform the swap. However, there is a logic flaw that can abuse the approve in the contract. The variable callproxy can be used to change the routing of where the funds go. In particular, the caller() of the contract for the safeTranferFrom() can be changed to be any user! By changing this, the previously approved aggregator will send funds on behalf of another user to you. The bug bounty submission process was quite sad. According to the Immunefi page, the max payout was 400K with a miniumum of 100K depending on current economics of the protocol. The O3 team claimed that since it did not work with a MAX allowance (which was used by default on the frontend) that this should be a medium instead of a critical. This shouldn't be the default on the frontend anyway and there are other ways to interact with the system besides the frontend. Trust pushed back at Immunefi, which eventually led to O3 being removed from the platform. He calls out Immunefi for being too lenient on projects violating the SLAs of the platform, which I agree with. Personally, I found the callout a little harsh with "We want each O3 user to know they are trusting a project that gives 0 ***** about their security and more likely than not will be featured at some point on rekt. When that happens, I for one wouldn't be shedding any tears." Running a profitable project is hard; taking 100K from a project could bankrupt it.
Analysis Summary
# Vulnerability: Arbitrary Token Drain via Aggregator CallProxy Logic Flaw
## CVE Details
- **CVE ID:** Not Assigned (DeFi protocol vulnerability)
- **CVSS Score:** 9.1 - 10.0 (Estimated - Critical)
- **CWE:** CWE-287: Improper Authentication / CWE-285: Improper Authorization
## Affected Systems
- **Products:** O3 Swap (DeFi Bridge and Aggregator)
- **Versions:** V2 Core
- **Configurations:** Specifically affects Aggregator contracts including, but not limited to, `O3EthereumUniswapV3Aggregator`.
- **Contract Address (Example):** `0x561f712b4659be27efa68043541876a137da532b`
## Vulnerability Description
The vulnerability exists in the logic of the aggregator's swapping functions (e.g., `exactInputSinglePToken`). The contract includes a `callproxy` parameter intended to facilitate swaps for the bridge utility. However, the implementation allows an attacker to manipulate the `caller` variable.
If a user provides a `callproxy` address and sets `amountIn` to 0, the contract sets the `amountIn` to the full allowance the `callproxy` has granted to the aggregator and reassigns the `caller` variable to the `callproxy` address. Because the contract subsequently calls `safeTransferFrom(caller, address(this), amountIn)`, it pulls tokens from the victim’s wallet (the `callproxy`) instead of the message sender. An attacker can set the `to` parameter to their own address, effectively stealing any tokens the victim has approved for the aggregator.
## Exploitation
- **Status:** PoC available; logic confirmed on mainnet forks.
- **Complexity:** Low (Requires specific swap parameters to ensure the transaction completes).
- **Attack Vector:** Network (External call to smart contract).
- **Condition:** The attack only works if the victim has approved a specific amount to the aggregator. If the victim used a "MAX" (infinite) allowance, the `safeTransferFrom` may fail or require more gas/liquidity than available, though the fundamental logic flaw remains.
## Impact
- **Confidentiality:** None
- **Integrity:** High (Unauthorized transfer of assets)
- **Availability:** High (Loss of user funds)
## Remediation
### Patches
- The O3 Swap project was removed from the Immunefi platform following disputes regarding the severity and remediation of this flaw. Users should verify if the O3 team has deployed updated Aggregator contracts.
### Workarounds
- **Revoke Approvals:** Users should immediately revoke any active token allowances/approvals granted to O3 Swap aggregator contracts.
- **Avoid Fixed Approvals:** The bug specifically exploits non-MAX approvals; however, MAX approvals present their own set of security risks.
## Detection
- **Indicators of Compromise:** Transactions to the aggregator contracts where `amountIn` is 0 and the `callproxy` parameter is set to a third-party wallet address.
- **Detection Methods:** Monitor for `Transfer` events where the `from` address is not the `msg.sender` of the transaction initiating the swap.
## References
- **Trust Security Blog:** hxxps://www[.]trust-security[.]xyz/post/critical-finding-stealing-tokens-from-o3-bridge-users
- **O3 Swap Documentation:** hxxps://docs[.]o3swap[.]com/o3-swap-v2-interchange#1.2-protocol-layer
- **Vulnerable Code Layer:** hxxps://github[.]com/O3Labs/o3swap-v2-core/blob/d1aef9f75b26bf7865785b1fd4748ff7c369c3da/contracts/aggregators/Ethereum/O3EthereumUniswapV3Aggregator[.]sol#L67