Special Edition: imBTC, Uniswap & dForce
Time to reset the "days-since-last-DeFi-attack" counter
|Apr 20, 2020||5|
It’s a late Saturday night and I’m watching a movie. 12am, movie finishes and I find out a new DeFi attack has happened. Spent till 2am researching, brain hurts from complexity. Looks like my Sunday is gone. Next morning I post this:
defiprime @defiprimeIt looks like LendfMe / dForce protocol being drained 🚨 https://t.co/UEqSEpSOfT
Luckily Frank Topbottom is on the ball and already decoding a bunch of on-chain data. Make sure to follow him to stay on top of what’s going on complex technical situations like these.
Here’s the rough TLDR of how this article is structured, feel free to skip to whatever bits suits you:
AMMs 101 - understanding how AMM curves work at a very high level
Reentrancy 101 - understanding what a reentrancy attack is and how it works
Uniswap x imBTC - initial attack that involves Uniswap
dForce x imBTC - second attack that involves dForce and $20m was lost
Hacker x dForce - dForce negotiates with hacker on-chain (yes, I’m not joking)
Implications - what can we learn, who is responsible for what
Closing - a reflection on how we did as a community and how the future might look
Automated Market Makers are exchanges that don’t have an order book. The price is determined by the ratio of assets in the exchange. The exchange relies on the formula below:
x * y = k
x = first asset (Ether)
y = second asset (some Token)
k = constant that must always stay the same
Here’s a little pictures the demonstrates how this looks practically:
The black line drawn is x * y
The gradient at any point of the curve indicates the price between ETH/Token. At the middle you have the real price, the further you move away the more slippage you experience.
To move up the upper left of the curve, you’ll need to have lots of ETH in the pool and not many tokens. Tokens are very expensive at this point (lots of ETH required to purchase a small amount of tokens).
To move down the bottom right of the curve, you’ll need to have lots of tokens in the pool and not much ETH. Tokens are very cheap at this point (lots of tokens required can be purchased with a small amount of ETH).
I’ll be writing a much more detailed post on DeFi Weekly about AMMs and a run down of who is doing what, but for now this should be enough to understand the attack that went down.
The second component to our understanding of the attacks that went down is what’s known as a reentrancy attack.
Put simply, a reentrancy attack is when unanticipated code is called in between existing code. How does that works? Let’s take a look at the most famous reentrancy attack: The 2016 DAO hack.
The attacker creates a contract which he executes the attack from. This contract has two functions. One to withdraw ETH from the DAO, the second that is called when ETH is received (standard part of any Solidity contract)
The contract calls the withdraw function and the first line of the withdraw function is to send the ETH to the person who requested the withdrawl
Since the requester is the contract and can call a function when it receives ETH, it then in turn calls the withdraw function on the DAO contract again!
He keeps repeating this until his balance is updated at the end, but only for 1 withdrawal, not the amount of ETH he actually withdrew!
The community learned this lesson for a hefty price of the hard-fork, however what makes our case interesting is that a new token-standard, ERC-777 actually introduces a deliberate reentrancy vulnerability by calling the sender of a transfer before the tokens are sent! Don’t worry if this last part doesn’t make sense, there’s more pictures for you below to understand.
Uniswap x imBTC
Part of what makes Uniswap amazing as an exchange, is that anyone can list any token without any permission! When Uniswap released v1 over a year ago, Consensys Dilligence did an audit for Uniswap and found a potential attack vector with the ERC-777 token standard and Uniswap (https://medium.com/consensys-diligence/uniswap-audit-b90335ac007). In fact, Open Zeppelin decided to even take it a step further and create a tutorial on how to use the exploit with some PoC code to help a future attacker: https://blog.openzeppelin.com/exploiting-uniswap-from-reentrancy-to-actual-profit/.
Now when the imBTC Uniswap pool reached a large size, someone thought “hey, this might actually work”. They gave it a go and turns out it actually did!
So what happened exactly? Here’s what:
The attacker purchases imBTC from the pool via Uniswap. The balance of ETH has increased and imBTC decreased.
He then sells half of the purchased imBTC from the pool, however as he is selling the imBTC the balance of imBTC hasn’t decreased
This is due to the ERC-777 reentrancy attack since he doesn’t actually end up selling the imBTC but instead is effectively draining the Uniswap ETH pool of ETH!
The attacker does not earn any money from the imBTC but the ETH from the pool. Uniswap LPs for imBTC were the real losers here.
The tokens have changed ownership at this point in time, however Uniswap doesn’t know that multiple calls have been made, it assumes just one has been made. Due to this it relies on faulty assumptions of what the numbers are and lets the attacker manipulate the math of the curve. I jumped on a call with Michael (founder of Curve) to better understand how this works in more resolution. Below are the notes I made with example numbers to get a better intuition of the numbers:
dForce x imBTC
By this point in time it was pretty obvious to any developer/protocol that touched imBTC this attack was possible. The BTC aggregator token, BTC++, immediately froze imBTC inside their contracts promptly - the correct thing to do. However, inside every DeFi hack story there’s always a twist.
Rewind to a few months ago, a Chinese team called dForce copied Compound’s source code, deployed on main-net and setup shop. Their whole angle was to be “the Compound of Asia”. Good in theory, except whether the team fully knew what they were doing was questionable. Crypto is one of those industries where you can’t use low quality developers since the cost of a mess up literally involves other people’s money. Regardless, dForce went ahead and started getting traction (not sure how much of this was recycled money though tbh). It got to the point where just a week or so ago, Multicoin invested $1.5m into dForce:
Mable Jiang @Mable_Jiang0/ Today I’m excited to announce that @multicoincap led a $1.5M round in @dForcenet, the world’s first "Super-network" for open finance protocols. Coinvestors include our friends at CMB International (CMBI) and @huobicapital. https://t.co/obXTCYUxIp
Large investor puts money inside DeFi protocol, said protocol is gaining traction - must be safe to put money inside? Absolutely not. Turns out that dForce uses imBTC inside its lending protocol, meaning someone can use imBTC to borrow other assets. Oh-oh.
This hack was more clever in how it made use of the reentrancy attack.
Hacker deposits a sizeable amount of imBTC into dForce. This is the amount of imBTC that gets registered on the dForce protocol
Our hacker then deposits 0.000001 imBTC into the protocol
The next step is to withdraw the first large deposit of imBTC but then invoke the reentrancy attack which means the protocol doesn’t register his withdrawal
During this reentrancy attack he then borrows other assets with his original imBTC deposit. Since his original collateral balance isn’t subtracted he can re-borrow many more times than his actual amount.
Through this he drains $25m worth of funds directly from dForce!
Hacker then deposits stolen assets into other DeFi protocols to earn yield (alpha move lmao)
Best on-chain example of what happened: https://bloxy.info/tx/0xe49304cd3edccf32069dcbbb5df7ac3b8678daad34d0ad1927aa725a8966d52a
A summary of the losses incurred:
List of victims and funds lost:
Hackers x dForce
You wouldn’t think it could get crazier than this could you? Sike! It does. After the dForce team realises they essentially lost all of their depositor’s money, they took an unusual tactic.
Negotiate with the hacker on-chain. Below is a little on-chain story.
You might be thinking, why bother negotiating with them in the first place? Well turns out that the imBTC is actually a custodial asset and the issuers will need to issue the redemption for real BTC in order for it to be useful. To be more concise, the imBTC is tainted and profiting from it will be difficult. Our hacker decides to come to the table instead. You can check out Frank’s remaining tweet storm for all the refund txs:
So now that we’re all on the same page about what happened and how it happened, let’s look at the aftermath of all of this. I’ll discuss party by party.
Uniswap. Were they responsible? Partially. While they had no role in listing imBTC, in fact they state that they don’t support ERC-777 they could have done two things in their control. First, detect non-ERC20 compliant tokens and warn users of using pools that don’t adhere to standard logic. Secondly, they could have used reentrancy guards that prevent a reentrancy attack from happening in the first place. I wouldn’t take pitch forks to them, but rather a lesson to protocol developers to think about external vectors like this and warn users.
dForce. Were they responsible for what happened? Absolutely. All assets listed on their platform should have been carefully looked at and analysed. In addition, they ripped off Compound’s source code without having the required expertise. Go-to-market was prioritised over users security.
Multicoin. While they were just investors, I think they do have a role to play given their prominence in the industry. They very publicly backed a team who, from what it clearly seems, did not have the required technical expertise to maintain a decentralised lending protocol. Copying and pasting code shouldn’t fully be crucified since everything is open source and innovation can be sped up from the trove of code already available. What is bad is when teams that don’t know what they’re doing copy and paste code. Small difference but large difference in outcome.
imBTC. It’s hard to say whether they were at fault here since they adhered to an approved token standard. They could have given a heads up to protocols they were going to integrate with that a possible reentrancy attack vector could be possible.
As for investors who are watching this from the sidelines, I’d imagine that any team which has existing Ethereum/Solidity knowledge would command a premium given the intricacies of how these things work. I always thought there would be an explosion of DeFi protocols but maybe I’d change my assessment to only the best can end up shipping and creating high quality software in the process. Reminder that talent is scarce in this industry.
I guess this wraps up this special edition of DeFi Weekly. This set of events really does seem like a wealth transfer from those who understand DeFi more deeply (hacker) to those who do not (dForce). Chasing yield blindly is a dangerous task and the risks should always be weighed up with the reward. One concern here is that this event, alongside many others, scares investors from investing in DeFi due to the compounding risk from tokens/protocols being pulled together. Kain sums it up pretty well:
Once again, if you enjoyed reading this article please share and subscribe! Thank you once again to Frank Topbottom for his great on-chain data.