How to steal $5M with a read-only bug

Devcon 8 · 4 Nov 2026 · 7:55

Security researcher Bartosz Barwikowski walks through a Move VM bug in which passing an object as both mutable and read-only yields a separate read-only copy. It looks like a dead end for two weeks, then a Python script over decompiled contracts finds about 500 candidate functions. Aimed at an algorithmic stablecoin, the bug becomes an exploit worth about $5 million in a single transaction.

Speakers

Topics

From Devcon 8, hosted by Ethereum Foundation.

Transcript

Hey everyone. So let's get started. Yeah, as Martin said two years ago it was 1.1 million. Since it was my first buck bounty, I got 50k from this. Since that my back hunter career started, I made more than $1 million from back bounties. Most of them hacken proof. So it was a crazy time. Yeah. Let's go straight to the back. So I was studying how the transaction uh processing and virtual machine works on uh move VM. So when you have a transaction you can call smart contract uh basically in few different ways and what is interesting that you can provide parameters by uh by giving just a single parameter or the

list. they have a different native implementation but uh what you can do is okay when you have some readonly object let's say you have some coins uh because in move VM everything is like an object you can pass many of them as a readonly objects but when you want to like do something with them and you have like multiple object you can only pass it once and you cannot have a situation where you pass multiple object and just a read only object but after studying this during studying this I found one exception there is a bug which uh allows you to do something which should be illegal. You can pass uh the same argument the same like coin as multiple object and also as read only object when you use an list for this. It was very

special edge case it only work worked when size of the list was one and I've noticed it. So yeah I had this bug now the question is uh what you can do about this bug. Okay, normally uh you would expect that when you pass many objects to the transaction, it will be represented in memory as a single object. So yeah, it makes sense, you know, you pass the same object many times, it should be the same object. But it wasn't the case. Every time you pass an object in a transaction like okay, you pass X three times, it's in the smart contract, you get a copy of the object. So it's copied each time. It's not the same object, it's a different one. It will be important because in

practice it makes an copy of the object and some objects like your coins, tokens shouldn't be possible to be copied. And by the way, it is a bug on itself because when you have a lot of objects, let's say 10,000 of them and each of them is 50 kilobytes and each of them is being copied. If you create a transaction which is like co using 10,000 of read only objects, it creates Daniel of service. So I got another bounty for that. Okay. So, yeah, but the problem with copy alone is uh that the read only copy is that you cannot really steal money with this because okay, when you want to send coins, when you want to like exchange them, you need this multiple uh

object. So, I spent like two weeks studying the code, searching the native contracts, and I couldn't find any way uh to really abuse it. So, I would get only like medium severity back, $10,000. So uh I started to dig deeper. So I started to searching in all deployed smart contracts. Okay. Is there any bug which I can abuse? I was looking for a very specific function. One which is taking uh some multiple object and another one as the read only object so I can uh somehow abuse it. And uh I had to decompile smart contracts and look over them. And I created a Python script which allowed me to like find 500

functions which uh had the situation where they accept mutable and nonmutable objects and after some time I managed to find where this attack uh can be executed and the bug would be in deterministic oracles which are the oracles which calculate the price automatically based on the liquidity pool. So let's say you have some uh pool uh where you like trade Ethereum for USDC and some oracle is reporting the price. So after you do a huge swap, the price is going to change. Uh yeah, you spend like $2 million, the price is moving 50 $50. And what you can do with this buck in practice is that okay, you

can make a snapshot uh of this uh oracle before the swap and after the swap. So you end up with two oracles giving you the same the one oracle giving you two different prices. So yeah the bug is there. The question is how to use it and I spent another days to find a perfect target for this and the target was uh uh algorithmic stable coins because they were like using uh Ethereum price or some other token price and they were giving you stable USD and I found and I found that you know by doing a loop where I first sell uh like Ethereum for the higher price then I'm using

different oracle price to to uh to buy them cheaper. I and I repeat this. I basically I'm able to get most of the money of uh of the treasure. So I started to create a contract uh to exploit this. It was quite complex thousand lines of code. I had to borrow $23 million from flesh loans to to to make it work. Yeah. But uh after working few days on this and uh simulating it on a copy on the mainet, I managed to do it and it was able to extract $5 million and get $5 million profits uh on the single transaction with like no gas, no no input uh of other coins at all. So

yeah and the important part is here that um without those many extra components like without the flesh loan without found deterministic oracles without algorithmic stable coins I wouldn't manage to get a critical I would only get $10,000 for medium severity but by combining so many things I managed to get it to to critical. Yeah. So that's the story from from this. Thanks. >> Amazing. Thank you B. Okay, we got time for maybe one, maybe two questions. So, if you're eager, please put up your hand and uh you'll get a box thrown towards you. Okay, there's one over here.

One question over here. This actually there's two, but we'll start over here. Make it a quick one. >> Hello. >> Okay. Uh how does uh security work now? Uh >> can you talk into the box? >> One, two, three. Okay, perfect. How does security work uh works nowadays that uh you know AI is uh doing a lot of work for auditors? Uh are you still doing security work? >> All right. Yeah. So it changed a lot. It changed a lot. You know AI changed the back bounties a lot and like I can find right now 80% of the bugs I was able to find. Next year it will be able to find it all. So we will have a lot of bugs found uh during next two years. It will

be crazy. And I'm not doing bug banties anymore. Uh to be honest, I'm started working on a company which does formal verification to find all those bugs and fix them. So I think this is the future of cyber security. >> Great. Okay. Yeah, I think we'll we'll wrap here, but if you have any questions for BS, I'm sure you can approach afterwards.