Saw DFX got hacked, decided to figure out what went wrong. Their own flashloan function got used against them. Read on for more [1/10]

To begin, the attacker contract hits the "flash" function. This function wasn't included in the public Git repo, which makes me think it was a recent addition, potentially one that didn't make the audit. [2/10]

Adding this after-the-fact was a mistake, but let's dig into how this worked. The function, to be a useful flashloan, must contain a callback. This is where our attacker gets in. [3/10]

To prevent someone stealing funds, the system records the balance of the tokens within it right before it sends this callback, then mandates that the balance after the flashloan equal or exceed the original balance. You can't not give back the funds during the flashloan. [4/10]

However, you can give them back by redepositing them. This is what our attacker does with his callback. He just calls the "deposit" function on the pool, which is not protected against reentrancy, forcing the contract into an insolvent state. [5/10]

It records that it owes him the full sum of what he just flashloaned from it. At this point, the deed is done, the attacker has convinced the contract it owes him its entire balance. [6/10]

The post flashloan checks pass, because the funds are still in the contract (even if the contract is now insolvent), and the hacker finally calls "withdraw" to finish out the theft. The entire pool is now drained. [7/10]

I'm sorry to the @DFXFinance team for what they're going through, know how this feels. Wish them the best of luck and hope they emerge from this situation all the stronger for having endured it. [8/10]

One point of advice: always use reentrancy protection, even when it seems totally unnecessary. Adding just one new function can turn formally secure systems into insecure ones very quickly. [9/10]

I'm bad at counting words and there actually is now tenth response. Hope this thread helps someone get better at security. [10/10]

Update: It appears that the "flash" function that enabled this exploit was a new feature in their V2. This version was audited by PickAx only and was outside the scope of the @trailofbits audit that covered their V1 [11/10]

Update 2: “deposit” is protected against reentrancy. However, since “flash” is not, this doesn’t matter, as the nonReentrant protection is never triggered at a point where it would mitigate anything

Follow us on Twitter

to be informed of the latest developments and updates!

You can easily use to @tivitikothread bot for create more readable thread!
Donate 💲

You can keep this app free of charge by supporting 😊

for server charges...