BarnBridge (
@Barn_Bridge) got drained for 770K USDC
The attacker never needed a bug in the code. They got the DAO to vote them the keys.
1β£ Background
BarnBridge SmartYield is a retired yield protocol. Its Compound USDC pool still had a live provider contract, a working DAO, and around 90 wallets that never revoked their old USDC approvals. All the ingredients were still on-chain, just unwatched.
2β£ The setup
1. The attacker buys BOND, the governance token, and stakes it in the DAO. In a DAO this dormant, that was enough voting power to pass a proposal on their own
2. They deploy an empty upgradeable proxy
3. They submit one governance proposal - hand pool control to that proxy.
Description: "migrate proxy implementation". During review it looks like control moving to a fresh, harmless contract
4. They vote for it, queue it, and wait out the timelock
3β£ The switch
Once the proposal executes, the DAO calls `setController` on the provider and points it at the attacker's proxy.
Only then does the attacker upgrade the proxy to the real drainer.
4β£ The drain
Now the attacker is the controller. Two functions finish the job.
`_takeUnderlying(from_, amount)` pulls USDC via `transferFrom` from any `from_`, gated only by "is the caller the controller".
They call it for every wallet that still had an approval and sweep all of it into the provider.
`transferFees()` has no access control at all. It reads the provider's full USDC balance and sends it to `controller.feesOwner()`. The attacker's controller returns their own wallet.
- 92 wallets drained
- 776,575 USDC out