Readit News logoReadit News
bombcar · 3 years ago
Apparently the coding mistake was identified and deemed "impossible to exploit": https://certificate.quantstamp.com/full/nomad

> QSP-19 Proving With An Empty Leaf

> Recommendation: Validate that the input of the function is not empty

> The Nomad team responded that "We consider it to be effectively impossible to find the preimage of the empty leaf".

> We believe the Nomad team has misunderstood the issue. It is not related to finding the pre-image of the empty bytes. Instead, it is about being able to prove that empty bytes are included in the tree (empty bytes are the default nodes of a sparse Merkle tree). Therefore, anyone can call the function with an empty leaf and update the status to be proven.

treis · 3 years ago
It seems like it was (at least arguably) impossible to exploit until they introduced a second issue:

>It turns out that during a routine upgrade, the Nomad team initialized the trusted root to be 0x00. To be clear, using zero values as initialization values is a common practice. Unfortunately, in this case it had a tiny side effect of auto-proving every message

EDIT:

Reading and noodling I'm 99% sure these are separate issues. The vulnerability talks about passing in an empty leaf to the prove function. But that's not what the exploit is.

The exploit is using an unproven message. So they are passing in an actual leaf to prove. The problem is that unproven messages have 0x00 as root and some jabroni set 0x00 as the trusted root. So every message was treated as proven by default when it should be the opposite.

bombcar · 3 years ago
Anyone who's studied NTSB reports knows this is almost always how they go; a single failure that is no problem becomes one because of some other issue that doesn't normally happen, or couldn't happen because normally a third thing is always done ...
klodolph · 3 years ago
I'm not completely sure the mechanics of this exploit, but I've recently adopted the personal guideline of "all enums and integer IDs start at 1", and 0 is simply an invalid value.

Not a hard and fast rule, and not something that will catch tons of problems, but now and again it does help me catch an uninitialized value.

mouzogu · 3 years ago
> routine upgrade

yes, a routine upgrade. that's what it was..... (→_→)

danielvf · 3 years ago
I don't think this is the same issue as the exploit.

The real issue was half-caught in a review on a pull request however. https://github.com/nomad-xyz/monorepo/pull/289/files

If this legacy enum value had been handled later in the code, there would not have been a vulnerability.

(This isn't to say that the developers were bad. The person who wrote the code was extremely knowledgeable. It's just really hard to be perfect every time. )

bigcat12345678 · 3 years ago
No, they are bad.

They are bad because they are not competent to write the decent code required by their profession and job environment.

In normal software writing trade, such engineers are called low performers and routinely managed out of any organization.

Sure, the mistake is not unusual from the perspective of general software engineering. But let's not forget what software they are working on.

I am totally fine with a bartender dropping a glass... I'll put a surgeon on trial if he cannot make his hands steady during a heart surgery...

Deleted Comment

drog · 3 years ago
That's common misinformation. The issue discussed in the review has no connection to what happened, and the narrative that it is the same issue, but it became exploitable after the update is incorrect too. It affects different part of smart-contract logic. Yes, it's pretty close at a glance—because you have zero-by-default problem somewhere close to Merkle tree.
jxi · 3 years ago
Quantstamp said it was exploitable. Nomad falsely claimed it wasn’t.
mhluongo · 3 years ago
They're two distinct issues in two distinct contracts, AFAICT.
edm0nd · 3 years ago
Another ouch

>Messages popping up in public Discord servers of random people grabbing $3K-$20K from the Nomad bridge - all one had to do was copy the first hacker's transaction and change the address, then hit send through Etherscan. In true crypto fashion - the first decentralized robbery.

https://twitter.com/FatManTerra/status/1554258880380772352

wnevets · 3 years ago
Since "code is law" doesn't that mean it wasn't a robbery? They were just following the law.
Vespasian · 3 years ago
Contracts (smart or not) cannot override the law.

I'm not a lawyer but I would be very surprised if courts in most countries would buy this argument.

Spelling or grammatical mistakes usually don't invalidate contracts in the real world and robbing a poorly secured vault is still illegal.

The thief was obviously trying to get other people's money without their consent.

TrapLord_Rhodo · 3 years ago
Nope - It's not a robbery.

The old mantra of possession is 9/10ths of the law is and always has been false. If i have something i own it. That is the one fundamental truth. Now someone can come and try and take it back from me by force (Person, Court System, Rebels, Corporations) if they can exert more violence on 'me' than i can exert on 'Them'.

The problem with crypto is the 'keys' are what crypto is. No nationstate can come and take that away from me. They can kill/imprison/fine me, but then neither of us will have it. You would have to hack/fork the chain for that to happen (Which has happened) or find some social way around it (If i have it on a centralized exchange, if i have a hackable hard drive, found my keys on AWS, etc etc.) Additionally, with things like Monero, and tornado swap good luck trying to find them.

adrr · 3 years ago
It will be interesting to see if they can prosecute people. They are called smart contracts and talked about being the actual contract.

Deleted Comment

chatmasta · 3 years ago
It looks like somebody had a bridge to sell them.
cellis · 3 years ago
It wasn’t a robbery! It was engineers dutifully executing the smart contract according to its terms!
rmbyrro · 3 years ago
> the first decentralized robbery

thanks for the loud laugh

some_random · 3 years ago
>the first decentralized robbery

This is the funniest thing I've read all day

kwertyoowiyop · 3 years ago
DeFi meets DeRob.
OrangeMonkey · 3 years ago
The international obfuscated c contest has taught me that programmers can make small mistakes on purpose and its almost impossible to identify legit mistakes from malfeasance.

If we have a situation where:

* Its hard to tell, after the fact, 'a mistake' was a bad actor.

* The programmers are, by and large, anonymous.

* The benefit of making 'a mistake' could be hundreds of millions of dollars that are not easily traced.

This situation seems rife for abuse and bad actors. Not saying it happened in this case. . . but how would you know?

nubb · 3 years ago
if you enjoy obfuscated c, we have this https://underhanded.soliditylang.org/
nyanpasu64 · 3 years ago
Reading https://blog.soliditylang.org/2022/04/09/announcing-the-unde...:

> In Solidity, the order of evaluation of sub-expressions is unspecified. This means that in f(g(), h()), g() might get evaluated before h() or h() might get evaluated before g(). Practically, this order is predictable, but Solidity code shouldn’t depend on that behavior between compiler versions. In most circumstances g() is evaluated before h() (left-to-right order), which is also the behavior that most languages specify in their standards. However, in the case of emitting an event with indexed arguments, the arguments are evaluated right-to-left.

I feel that order-of-evaluation dependence is a special case of the general conflict between expression-oriented (functional-style) programming, and impure operations requiring sequential reasoning. Another case of this conflict is temporary values (expressions) with side-effectful destructors (sequential reasoning), for example https://fasterthanli.me/articles/a-rust-match-made-in-hell#w....

At this point, is it good practice to avoid using side-effectful procedure calls as parameters to other expressions (especially those with multiple inputs), but instead first assign to a temporary value to make order of operations explicit?

tgv · 3 years ago
I've always enjoyed the underhanded C contest, but I don't think it's active anymore. Thanks for this. The 2022 entry that I saw was very much in the same spirit.
OrangeMonkey · 3 years ago
I am 98% anti-crypto, but this is awesome.

Thank you man!

rmbyrro · 3 years ago
> hundreds of millions of dollars that are not easily traced

If they keep it in blockchains only, it's hard to connect to a real identity. But if they cross the line (which is everybody's goal eventually) to the real world, they can get caught as easy or even easier than in traditional financial system.

chernevik · 3 years ago
This.

I don't how anyone would commit anything more than pocket change to a scheme where an insider could deliberately introduce a weakness and then exploit that weakness to walk off with all the funds committed.

jpmonette · 3 years ago
Isn't the same thing for oss contributions, npm packages, etc.?
cmeacham98 · 3 years ago
Slipping an exploit into an npm package doesn't let you easily run away with tens/hundreds of millions of dollars in the same way web3 projects do.

That said, I personally doubt this happens much if at all, because if you want to scam on web3 you can just do a good old-fashioned pump&dump and nobody seems to be receiving any legal/criminal consequences as of yet.

Destiner · 3 years ago
"Never attribute to malice that which is adequately explained by stupidity"
efitz · 3 years ago
Reason #5734 why cryptocurrency is a non starter for real people.

Challenge: explain to a normie that their life savings is gone forever because of a zero initialization vector.

gillesjacobs · 3 years ago
Challenge: explain to a normie that their life savings is gone forever because of mortgage backed derivatives.
TomVDB · 3 years ago
The first challenge is to find those normies.

Somebody who directly invested in MBS is by definition not a normie.

quickthrowman · 3 years ago
‘Normies’ didn’t lose all of their money selling credit default options and swaps on mortgage-backed bonds. They wouldn’t have access to the markets for those instruments or the capital to do so, and if they had access or capital, they weren’t a normie.
g8oz · 3 years ago
"The Big Short" did it pretty well.
happytoexplain · 3 years ago
Bad analogy. This explanation has actually been done pretty reasonably by a few people. Further than that - after such explanations, it's clear even to normal people who's to blame, whereas software and cryptography are much more esoteric in that department.

Of course there is no justice in either case, but at least normal people can see who is most appropriate to behead in the case of the traditional financial catastrophes, in the purely theoretical revolution.

davewritescode · 3 years ago
What a dumb retort

If you got burned by mortgage backed derivatives and lost your life savings, it's ultimately because you were (knowingly or not) speculating on the value of real estate assets and making an assumption about future values of said assets.

In the case of Nomad, it's that you put yourself at risk by using their service you could've lost everything you put in.

NaturalPhallacy · 3 years ago
>Challenge: explain to a normie that their life savings is gone forever because of a zero initialization vector.

You mistook a currency for an investment opportunity, and gambled your life savings on one thing. Currencies have always and will always fluctuate against each other. Diversify your investments.

onion2k · 3 years ago
I don't think that helps. Saying "5% of your money is gone because a developer fucked up, and you have no recourse." isn't going to go down well with anyone.
scottiebarnes · 3 years ago
Why are "normies" keeping their life savings on platforms whose express purpose and utility is cross network token swapping?
Vespasian · 3 years ago
Because their loved ones, or peers or Facebook advertisement told them it's safe and a good way to stick it to the man.

Usually just depositing money in a bank doesn't get it stolen so the assumption isn't unreasonable.

Even if it's only 0.25*life saving that's still devastating for most people.

dcolkitt · 3 years ago
They’re not. The vast majority of early liquidity in this and most DeFi protocols is raised from institutions, VCs, and trading firms.

This is especially the case for protocols like Nomad that don’t yet have a native token. They’ll get liquidity commitments through over-the-counter SAFT agreements that give the VCs a percent of the future tokens.

woah · 3 years ago
The reason this happened is that Nomad's contract was "upgradable". This is a pattern where the source code of a contract is able to be replaced by a privileged developer account. This was not how Ethereum was intended to work and it actually needs some pretty convoluted stuff to make it work (see the UpgradeBeacon related code here: https://etherscan.io/address/0x88a69b4e698a4b090df6cf5bd7b2d...)

The reason developers make their contracts "upgradable" is simple greed- they want to be able to launch more quickly than other projects without needing to ensure their code will stand the test of time. This may be OK for a social networking app MVP, but it's not OK for a smart contract which a user ideally should be able to audit and understand (or at least rely on the audit of someone else). "Upgradable" smart contracts can always be changed after the fact, as happened here, which means that any audit is meaningless.

Top tier projects still do use simple un-upgradable smart contracts. Uniswap first wrote v1, then improved it and launched v2, then v3. The Uniswap v1 and v2 contracts are still running and usable, and will be for as long as Ethereum is around. Their security properties will always be the same as they were the day they launched.

"Upgradable" contracts mean that you are trusting your money to some anonymous fat fingered (or at worst, criminal) dev, and it could disappear at any minute. They defeat the entire purpose of even using a blockchain.

artdigital · 3 years ago
Yes - but not having them upgradeable means that if your contract is dealing with a lot of money and a small bug was discovered, you are unable to patch it after the fact, even if people are actively abusing that bug

It’s not really about greed. Deploying a program and having it unchangeable forever comes with risks, and more often when dealing with very complex applications, those aren’t worth it

cypress66 · 3 years ago
People should NEVER touch any upgradable contract. It is literally centralized, and defeats the whole purpose of DeFi.

Yes, writing perfect code is very hard. But smart contracts are an example of code that must be extremely thoroughly tested, formally verified and so on.

But that doesn't go well with being first to market, move fast break things, etc.

saurabh20n · 3 years ago
For the curious, here are direct links:

* Initialization was done 42 days ago: https://etherscan.io/tx/0x53fd92771d2084a9bf39a6477015ef53b7... -- "Click to see More" and notice "Input Data" parameter [2] which sets _committedRoot to 0x00.

* Click through the To contract to get to the code (click on Contract tab): https://etherscan.io/address/0xb92336759618f55bd0f8313bd8436...

Just adding direct links to what samczsun and 0xfoobar are talking about in https://twitter.com/samczsun/status/1554260106107179010 and https://twitter.com/0xfoobar/status/1554269071214088193/phot...

what-imright · 3 years ago
Are you kidding me? They lost 150 million dollars and the only penalty is to write up the bug on twitter? These children are playing with peoples lives. There’s a body count to losing that much money
andrewia · 3 years ago
This is a really severe heist, but the latter part of your comment seems rather dramatic. Crypto is still generally not a medium of exchange, and most users are still speculative investors. Most of these investors have a hedge (or are using crypto as their hedge), except for the foolish.
perlgeek · 3 years ago
There a monetary value you can attach to a human's life, as much as that seems to be taboo.

Depending on how you measure, that value is (in the US and Europe) typically in the order of 1..5 Mio USD.

So it's not outrageous to assume that losing 150m comes with a body count, even if the funds wouldn't have bee used to directly save or improve lives otherwise.

sosodev · 3 years ago
Most perhaps, but stories of people committing suicide after every crypto crash are far too common...
fanf2 · 3 years ago
But when someone wisely observes that crypto is useless for anything except scams, some cryptoenthusiast answers, but no, it is useful as a medium of exchange for people in third world countries with difficult foreign exchange restrictions.
cuteboy19 · 3 years ago
Read the crypto subreddit. Most are fools
yieldcrv · 3 years ago
People are often in a prisoner’s dilemma, where they are relying on the developers/team to spearhead the investigation including the judicial investigation against the perpetrators with the chance of their being a financial remedy

and so therefore nobody is trying to kill or impair the developers/team

if you were referring to people committing suicide or being suicided by the people they borrowed money from, thats not everyone’s problem and people in those circumstances should re-evaluate to avoid that risk or accept that risk

676234e117 · 3 years ago
It is important that users come to better understand the different risk profiles between:

1. Owning ETH with a non-custodial wallet.

2. Owning ETH on a CEX.

3. Depositing ETH into a smart contract to receive a wrapped asset. This includes rollups and L2s.

The majority of major crypto hacks[1] are in the 3rd group, and almost all of these hacks are related to protocol updates and governance. Either: the developers update their code, and accidentally push a bug, or one address or a group of addresses are allow-listed some privileged actions in the contract and that can become a weak point.

Proxying and governance isn't the only way to design contracts. Two examples counter to this that are more robust are WETH ($6B) [2] and ETH2 Deposit ($20B) [3] which cannot be attacked in this way. If users wanted a new feature from the WETH contract, they would have to manually migrate over to the new address. Eventually we might see this kind of design be applied to bridges and rollups.

[1] https://rekt.news/leaderboard/

[2] https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead...

[3] https://etherscan.io/address/0x00000000219ab540356cbb839cbe0...