Rekt Retweet #6: Re-entrancy and Flash Loans - Why the $80m Fei / $Rari hack could NEVER happen on #Radix.

This is a complex one, so strap in!

go.radixdlt.com/rekt-retweet-6…

Thread 🧵👇 (1/22)

$XRD
The incident in question, courtesy of @RektHQ


(2/22)
TLDR: #Ethereum relies on messages, callbacks, and complex execution stacks requiring re-entrancy. This enables exploits if there is even one mistake in the ordering of logic.

On #Radix, re-entrancy is disabled by default, and so this hack could never happen on Radix.
(3/22)
$Rari Capital’s Fuse is a fork of Compound on #Ethereum. Fuse allows anyone to create their own lending and borrowing “pools” using any combination of ERC20 tokens. Both lending and borrowing is fully collateralized.
(4/22)
In the following hypothetical Fuse Pool, a user deposits 4,000 $USDC to borrow 1 ETH. If they want their 4,000 USDC back, they must return $4,000 worth of tokens, plus interest.
(5/22) Image
The $Rari Fuse Pool smart contract records that it has lent the ETH, preventing the $USDC collateral from being withdrawn. But this did not follow the recommended “check-effect-interaction“ pattern, as the $ETH is sent before the borrow record is updated.
(6/22)
On May 1 2022, a hacker was able to steal ~$80m worth of tokens from a variety of Fuse pools. For one example pool, they started by borrowing a 150m USDC flash loan from Balancer, and deposited that in the Fuse Pool’s account.
(7/22) Image
Next, that 150m $USDC was used as collateral to borrow 1,977 ETH from the Fuse Pool.
(8/22) Image
But before the Fuse Pool smart contract was able to update its internal borrow record (the effect), the hacker’s contract performed a re-entrant call to the Fuse Pool contract to withdraw the 150m USDC, and pay back the Balancer Flash Loan, allowing them to keep 1,977 ETH.
(9/22) Image
So why couldn’t this hack have happened on Radix’s upcoming Babylon release?

First, let’s understand how transactions (tx) differ between #Ethereum and #Radix.
(10/22)
On Ethereum: (1) Transactions can only call a single smart contract function, which sends messages downstream to other contracts which sometimes “callback” to the original contract.

This results in complex execution stacks for which re-entrancy is a vital feature.
(11/22) Image
(2) With all these interactions, Solidity smart contract developers always have to worry about their contract interacting with potentially malicious code in other smart contracts.
(12/22)
On Radix: (1) Users define all asset movements across all components in the tx manifest. If one step doesn’t execute, the tx fails safely. This lessens reliance on contracts messaging or calling back to one another, eliminating the need for re-entrancy.
(13/22) Image
(2) Resources (tokens) are “physically” sent between components in temporary containers called “buckets” that must empty by the end of the tx, or the tx fails. Scrypto developers no longer have to think about untrustworthy code in other components - as their code...
(14/22)
...interacts with the bucket. And when receiving a token from a bucket, users and components can select where to deposit the tokens, improving composability as deposits don’t have to specify a particular account.
(15/22)
With all this in place, this means that in Radix, re-entrancy is disabled by default, Scrypto developers can write simpler, clearer applications to achieve equivalent functionality without re-entrancy!

(16/22)
Here is “Rari” on Radix. All the resource movements are specified in the transaction manifest. The resources physically move between components. And Radix Engine combined with buckets guarantees the correct resolution of all the resources in the tx.
(17/22) Image
For the attempted hack, the hacker obtains a flash loan of 150m USDC, deposits it in “Rari”, and obtains a loan of 1,977 ETH. They then attempt to use their component to re-enter the “Rari” component mid-execution, in order to withdraw the newly deposited 150m USDC…
(18/22) Image
...before the Borrow Record is updated.

However, it can’t, as re-entrancy is disabled! The hack is thwarted, even with sloppy code by the developer.
(19/22)
Also, notice how the transaction has a “receive repayment burden” as part of step 1? That’s a temporary #NFT that the “Balancer” component requires the transaction to include when giving out a flash loan. If the transaction can’t resolve the burden, then it fails.
(20/22)
If you’d like to learn more about #Radix Engine and how it makes #DeFi and your tokens on Radix far more secure, visit developers.radixdlt.com

(21/22)
For the last tweet thread in this series, check out Rekt Retweet #5: Why the $30m Spartan Protocol hack could NEVER happen on #Radix



(22/22)

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Radix - Radically Different DeFi

Radix - Radically Different DeFi Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(