An explanation of the NFTTrader hack that resulted in millions of dollars worth of NFTs stolen 🧵:
(TLDR; combination of reentrancy + old approvals that were never removed)
The attack starts by calling the NFTTrader contract and creating a new "swap intent" (createSwapIntent).
Normally two lists are provided - a list of tokens that the swapper wants to give up, and a list of tokens to be received.
For this attack, the former list was empty.
The attacker also created the swap so that the receiver of the swap is also the attacker's address. Normally this value (addressTwo) should be the counter party (someone else).
The result is that both of the swap's parties are the same address - it's a self-swap.
The last important piece of info to note is that the swap includes an arbitrary NFT (a UniswapV3 LP position) alongside the actual stolen NFT.
This might seem random, but it's used to conduct the reentrancy exploit. This random NFT is always the first NFT in the swap.
After the swap intent is created, the attacker calls closeSwapIntent to initiate the transfer of assets.
The first asset to be swapped is the UniV3 NFT. The source and destination addresses of the transfer are both the attacker's address here.
safeTransferFrom is dangerous because it has a callback that's triggered after the transfer is done. This is what can lead to reentrancy attacks.
In our specific case, the safeTransferFrom is also called with data - this is where the victim's address is embedded.
The safeTransferFrom function is executed, which calls back into the attacker's contract with the victim's address.
The malicious contract then calls the NFTTrader contract's editCounterPart function.
Remember how the swap was originally a self-swap?
The attacker uses editCounterPart to change the counter party to the victim's address.
This is the first phase of the attack. The swap is now a swap between the attacker and the victim.
Now we go back to the original call context. The UniV3 NFT was just self-transferred, and the counter party (addressTwo) has been switched to the victim.
We then go to the next NFT to be transferred - the BAYC in this case.
Previously, the "from" value was the attacker's address. Now it's the victim's address.
The second critical part of the attack is that the victim had an old approval that allows the NFTTrader contract to transfer around the victim's BAYC NFTs.
That's what allows the safeTransfer to work. Had the user revoked approval to the NFTTrader contract, this attack could not have happened.
Unfortunately, the combo of reentrancy + old approvals led to NFTs being stolen.
The easiest way for this attack to have been prevented is if NFTTrader had a reentrancy guard on the editCounterPart function.
This would've prevented the malicious contract from changing the counter party during a swap.
Inscriptions have taken down multiple chains and caused huge gas spikes over the last couple of days.
However, very few people actually understand what's going on.
Here's a simple explanation of inscriptions - how they work and why they're being spammed everywhere 🧵:
The concept of Inscriptions started with Bitcoin's Ordinals. Ordinals allow data to be inscribed directly on chain - this can be text, images, videos, etc.
This is the only way for BTC to add support for NFTs and other tokens since it doesn't support smart contracts.
People then realized that they could do the same thing on Ethereum (and other EVM-based chains).
Instead of inscribing data on individual SATs, EVM inscriptions inscribe data in transaction calldata.
Celestia, one of the pioneers of the modular blockchain model, is now live with their mainnet.
Celestia's data availability layer has the ability to reduce costs and increase throughput for rollups by orders of magnitude.
Here's a high level overview of what Celestia is 🧵:
Data availability refers to a blockchain's ability to supply data that enables anyone to verify the chain's state.
For rollups, this data is posted to another source (Ethereum calldata, another chain, or a DAC), from which the rollup inherits several security properties.
These include the DA layer's censorship and re-org resistance. The more secure the DA layer is, the more secure the rollup is. The DA layer also determines the rollups final txn order.
If this is confusing to you, I did a beginner's intro to DA here: .
From a user's point of view, using a rollup is very similar to using mainnet - the main difference is you have a different network (RPC) for the rollup.
However, when you go to submit a txn, you'll see that it takes 1-2 seconds instead of 12 seconds like mainnet.
A lot of people don't know this, but over 90% of the blocks in Ethereum are built by MEV block builders.
Sounds scary, but you shouldn't be worried.
An explanation of why this happens, and how it keeps Ethereum decentralized🧵:
The mental model a lot of people have for an Ethereum txn looks like this:
user wallet -> full node -> public mempool -> validator -> consensus
However, the step between the public mempool and the validator is actually drastically different in most cases.
This is due to something called "proposer builder separation", or PBS.
PBS is important in preventing centralization at the validator level. Let's imagine a world where validators are both building blocks and proposing them to the rest of the network.
Normally, smart contracts are written in Solidity, Vyper, or Huff because these languages have compilers that compile the human-readable code down to instructions that the Ethereum Virtual Machine (EVM) can read.
Languages like JS, Rust, and Go don't have EVM compilers.
Remember that rollups are just blockchains at their core. And in order to use a blockchain, you need some funds to pay for gas fees. Most Ethereum rollups will use ETH as the native gas token. You need to acquire ETH on the rollup somehow.