# Auctus ACOWriter: arbitrary call drains approved USDC

Auctus ACOWriter's write() made an arbitrary external call, letting an attacker invoke USDC transferFrom to drain a victim's approved USDC.

- Payout: Real-world hack
- Severity: critical
- Program: Auctus
- Analysis by: DeFiHackLabs
- Disclosed: 2022-03-26
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2022-03/Auctus_exp.sol
- Library page: http://bugbountylibrary.com/r/dhl%3A20220326-auctus
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity vuln:access-control vuln:business-logic

**Target:** ACOWriter contract on Ethereum mainnet
**Root cause:** ACOWriter.write() accepted an arbitrary address and calldata and executed it as an external call, without restricting the target or selector.
**Steps:**
1. Fork mainnet at block 14460635.
2. Call `acowrite.write{value: 1}(address(this), 1, address(usdc), abi.encodeWithSelector(bytes4(keccak256(bytes("transferFrom(address,address,uint256)"))), 0xCB32033c498b54818e58270F341e5f6a3bce993B, msg.sender, usdc.balanceOf(0xCB32033c498b54818e58270F341e5f6a3bce993B)))`.
3. The writer executes USDC.transferFrom from the victim (0xCB32...) to the attacker for the victim's full USDC balance.
**Exploitation:** Attacker calls ACOWriter.write with target USDC and calldata transferFrom(victim, attacker, victimBalance). Because the victim had approved USDC to ACOWriter, the transferFrom succeeds and drains the victim's USDC to the attacker.
**Insight:** When a contract exposes a generic 'write' or 'execute' that takes an arbitrary target and calldata, check whether it holds token approvals; any approved token can be pulled via transferFrom.

