Imagine being able to control vast amounts of capital and do whatever you want with it for ~15 seconds (1 Ethereum block). Well, that’s exactly what flash loans let you do and it can lead to some really creative use-cases.
The image above may mean seem like just another Ethereum transaction to you at first glance but in reality it’s showing how an attacker was able to drain hundreds of thousands of dollars from a Balancer pool and make off with lots of ETH and tokens in just ~15 seconds. The attacker was able to do this in one Ethereum transaction because they utilized what is known as flash loans - a mechanism in which you can borrow any amount of capital you want from platforms like dYdX and Aave with no collateral as long as you pay it back within the same transaction. If you don’t pay it back, then the entire transaction reverts and the blockchain will act like it never happened (as the transaction wasn’t included in a canonical block).
So, how did this attack go down? Here’s a simple step by step of one of the transactions (as detailed here):
Attacker borrows 104,000 WETH ($23.6 million) from dYdX using a flash loan.
They swapped the WETH with the STA token 24 times to drain the STA balance in the Balancer pool. This was possible because STA is a deflationary token which means that each time it is transferred, there is a 1% fee charged which led to the Balancer pool receiving 1% less STA than expected.
The Balancer pool was then left with 1 weiSTA (0.000000000000000001 STA).
Then the attacker swapped this 1 weiSTA with WETH multiple times and because of the STA transfer fee, the pool never receives STA but still pays out the WETH.
This same step was repeated to drain SNX, WBTC and LINK from the pool.
Finally, the attacker repaid the 104,000 WETH flash loan to dYdX, increased his share in the Balancer Pool (BP) by depositing some weiSTAs, then swapped the BP tokens to 136,000 STA on Uniswap, and then swapped that STA to 109 WETH again.
The Balancer Pool lost almost $500,000 while the attacker made off with ~$425,000 of ETH and tokens.
The attack was over before anyone even knew it was happening.
Worth noting that there was a second similar attack about ~50 minutes later that effected the STONK token.
So, how do you stop this attack? Well, you’d have to be monitoring the Ethereum mempool in real time. The mempool is where all pending transactions go before they are mined and included into a block. So to stop this Balancer attack, you would of had to have been monitoring the mempool for someone using a flash loan to interact with a Balancer pool (which is actually a legitimate use-case for arbitrage). Then, you would have a maximum of 1 Ethereum block (~15 seconds) to respond and thwart the attacker.
In theory, there are three ways you can do this (if you detect the attack):
You send a lot of transactions to basically clog the entire Ethereum chain so that the attackers transaction won’t be included. This can be very costly and is not guaranteed to work.
You front-run the attacker by doing the exact same thing they are doing but spend more on fees so that your transaction is included first. This is next to impossible as well because you would have to learn what the attacker is doing and then formulate a way to front-run them in just ~15 seconds.
You somehow freeze your protocol using your admin key. This is also next to impossible as admin keys are usually controlled by a multi-sig and coordinating a multi-sig transaction within ~15 seconds is just not going to happen.
There is a fourth option though - and that is taking into consideration attacks like this when actually building out the protocol. The way I see it, there are at least 3 different top-level categories that developers must be aware of when designing their protocols:
Smart contract exploits/bugs (TheDAO hack due to a bug in the code)
Mechanism design flaws (like the Keeper bots that failed on Black Thursday with MakerDAO due to high gas prices)
Economic design flaws (like what happened with Balancer)
Though it is worth noting that this attack wasn’t actually an exploit in the Balancer protocols itself because it only affected specific tokens (in this case, STA and STONK). I would classify it as an “economic design flaw” because Balancer Labs was made aware of this attack vector by Hex Capital on May 6th but did not heed their warning and put in defensive measures (such as a whitelist for tokens) to prevent this.
In the end, Balancer Labs announced that they will be fully reimbursing all of the funds that were lost in these attacks and paying out the original bug bounty to Hex Capital which I think is a really great outcome for all involved.
Have a great day everyone,
If you’d like to support my on-going work to bring you a fresh Ethereum-packed newsletter every week day, feel free to make a donation on Gitcoin here (during the current matching round a 1 DAI donation is currently being matched on my grant by 39 DAI)!
All information presented above is for educational purposes only and should not be taken as investment advice.