The DeFi Walkaway Test: Can Users Actually Leave?
Devcon 8 · 5 Nov 2026 · 24:58
Diego Siqueira, a staff engineer at Zircuit, presents the DeFi walkaway test: if a protocol's team disappears and there is no website, API, indexer, block explorer or documentation, can a user with only their own node still get their funds out? Using a forked chain and the 100th biggest holder of each protocol's token, the talk traces a full Lido exit from raw logs and opcodes, ending at a permissioned batch step that blocks withdrawal. Results across protocols range from blocked exits to clear ones such as Rocket Pool, Compound and Fluid, followed by recommendations for builders and users.
Speakers
Topics
From Devcon 8, hosted by Ethereum Foundation.
Transcript
Yeah, the idea is to see like can the users actually leave the D5 protocols? I remember in 2020, 2021 when D5 was exploding and I was just learning about how things would work was working and what D5 was and how that was all behaving. And I found like one cool protocol that was called I think Red Skeleton D5 and deposit some money on it and everything was working fine. I was making I was seeing money going going up. Perfect. But then I just forgot about that, didn't get excited and a few months later I went to check their Telegram group to see how that was going and there was like a huge message from the founder saying, "Hey, I'm not
maintaining this anymore. I'm not going to do anything and yeah, that's it." He didn't rug, he didn't do anything, but there was no maintenance at all. The team just disappeared. So, the idea here is to see that. Like you deposit some money on a protocol and the team disappears. There's no uh website, there's no API, there's no block explorer, there's nothing. Like the contracts are immutable and they're going to live in the chain forever, but how can you get your money out? Like you don't know anything about that. So, I tested the protocols. I tested a few of them and I invite you now like to just take a look and try to make a mental bet of which protocols do you think users can actually leave if there's no team, there's no maintenance,
there's nothing. And at the end we're going to see like which ones pass the test and which ones are not there yet. So, this is the test and so what we have is exactly that. We have an address, we have our private key and we have a node. Like how do we get out? How do we get our money back? We don't have website, API, indexer, block explorer, nothing like that. We don't have the documentation, we don't have the API. So, how can we do this? So, how a run works. I executed a run on all those DeFi protocols, but how that goes is that those are the top protocols on Ethereum, uh mostly by TVL.
Uh and I try to see like, "Okay, what's the 100th largest largest holder that we have on on the token on that main token? And is is that a plain wallet or is that a contract?" So, I'm going to go to the closest plain wallet that we have. And we're going to run this on a midnight fork, and it's going to be the same block for all the protocols. Uh and the how that's going to work. Uh first, we're going to find the position. We We don't know the contract. We don't know the address. We don't know anything. So, we need to find that. And we're going to need to find a protocol the contract, learn how to exit, impersonate that wallet, try to do it on the fork, and then prove if there are any blockers.
Uh our main case is going to be Lido. It's the biggest TVL on DeFi Llama. So, and there was like a pretty interesting run. So, let's go over that. Uh our 100th largest holder is DE80. Uh it has a 5,000 uh stETH. It's a plain wallet. So, there is no code, no smart contract. It deposited 5,000 ETH in February. And that's the block that we're going to run our uh test. And the main idea here is that a developer is doing this, right? It is someone that knows how Ethereum works. It knows how the chain works, all that. But it has no protocol knowledge. So, we don't know how Lido works or any of of the other protocols.
So, all right. First step is get information. Like, let's try to get as much information as we can before starting anything. So, just running through the standard uh RPC JSON RPC calls. So, let's see. We found the balance. We found the nonce. So, that address already executed 36 transactions. There's no code. It's just a plain wallet. And here is where it gets interesting. So, we start we have our own node, right? So, let's hammer that node to get as much information as we can. We're going to get all the transfer transfer single transfer batch from block zero until the block that we're running the fork. And for all for all those transfers, we're going to see we're going to call that contract and
call name symbol decimals balance off to see which tokens were transferred for that for that wallet. And we find this. So, you can see the first one is a pretty compelling contract. The name is liquid staked ether 2.0. The symbol is stETH. So, that's more or less what we're looking for, but we can also see that there was a bunch of scam coins, address poisoning, fake airdrops and all that. Actually, found 78 contracts when doing this test. So, but we don't know all right. We don't know which one is the the right the correct one. So, we need to verify that. We shouldn't trust any of these contracts or what they say.
So, the first one matches the name that kind of makes it simple, but let's prove that. So, any contract can emit a transfer event. So, that's not what we're looking for, but let's look at the first contract. So, the first event is what we can see on the top and we can see that that contract it has three topics. The first topic is just the signature, but we can see that this is a mint and this end it who is receiving that is actually who sent like his our our contract the EA0 and it's he received it 499999 of that token that's called stETH. So, that's pretty good. And but looking at the the event we can find a transaction hash and with the transaction hash we
can see who sent that transaction that transaction. And we can see that the EA0 was actually the sender of that that transaction. So, we know that that guy is sent 5,000 ETH and received 5,000 stETH back. And he initiated the trans that that transfer that transaction, right? So, none of the other 77 contracts have this. None of those are initiated by this guy, by the sender. So, we know that that is our contract. Now, we can see like, okay, we have the contract. And if we call something like name on that, like let's see the debug trace for that call. And we can see that that call calls another contract, which is a proxy. And that's
actually a proxy to a proxy. So, we find that the real contract that's answering is 0282. So, that's our real contract. We found that. And with that, we can get the code um we just using a plain get code and disassemble that to get the open opcodes for everything on that. And the cool thing here is that we need to try to find which functions are in there. And to do that, we can look It's not perfect, but it works quite well. We can look at the push four and the EQ opcodes. If we have a push four and then we have an EQ, that's most likely a function call. So, looking at this contract, we find 86 candidates.
Uh nine of them we can quickly match to your C20 uh signatures, so that's fine. Uh but the other 77 we don't really know. I tried to brute force a few signatures, but none of them uh returned anything on either. Uh but okay, so we gather all the information. Now, let's watch the others. What are other people doing with their ST ST ETH token? Uh we get Let's see like what's the window that we're going to do. That's going to be 7 days. And we're going to get every transfer that's happening with ST ETH.
How that works? Like what we're trying to see is people they get ST ETH, what they do with that. So, going through every transfer, we're going to get every contract We're looking for contracts. Like which contracts are people sending this ST ETH to? So, we're going to get all those addresses that made transfers. And then we're going to group them by direct senders and the amount sent. And here we can see the results. So, on the top table you can see the top five contracts that received different calls from different senders. So, the first one it's a clear leader. And you can actually see that this first contract the 889e it's on both tables. So, it's
the first contract that received transfers from more from different senders and it's also the second that received the most amount of ST ETH. So, this is a pretty good candidate that we know that okay, that's probably an an important contract for these ecosystems. So, let's take a look at this contract. Uh looking at this contract we can see that uh there was looking at ST ETH, right? So, we can see that there were a lot of mints, not that many burns. Uh and that contract's pretty important. And these are the top three selectors that people called when interacting with that uh with that contract.
And let's just take a look Okay, so the first one is here the ACF4. So, that's the most con- the most used selector when doing interactions with that contract. So, let's take a look at that uh transactions for that. So, when people call ACF4 there's always these events that gets published on the transactions. So, looking at this trans- these events we can start to see a pattern. We can see that these events they all have these four topics, which are pretty standard.
Uh if you have been looking like you it looks like an NFT minting. You can see that if from address is the mint address, the two address is our address. And then is the caller address. And then the third the topic three is the ID of the NFT. So, what people are doing is that they are sending the STF to that ad to that contract with that selector and they're getting back one NFT number a number NFT.
All right, so that's first That's uh easily first you see like okay, people are getting this STF and they're sending they're getting this NFT. And we can actually prove that that's a transfer by just getting the signature for the transfer. So, and we can also act also call the owner of just to prove that this is an NFT and that works. All right, so now we know that people are sending that, but what else is happening? Like what do we do with this NFT? So, we can see that by looking at the get if the get logs for that event for that contract, we can see these are all the events that are emitted by that contract.
Uh the first one is the transfer we just proved that and we can see the breakdown on the top on the top left. Uh we can see that 616 uh of those transfers were mints. They had the original address as the zero address. Uh 665 were burns. They had the destination address as the zero address. And just two of the of the transfers were between wallets. Uh but okay, so we know that there's a high high correlation between those transfers and those those transfers and the mint and burns.
But what's interesting here is that we can see that we have 616 mints. That's on a transfer event, right? But we also see that uh F0C4 has exactly the same number. And by doing some correlation, we can see that every time that there's a mint, that event is also emitted. And the same goes for our burns. So, we have 665 uh burn events and we also have 665 682 events. Um perfect. And now so, we are more interested in burns because that's usually the pattern that goes like. So, how that goes, let's take a look at the selector that's most used to cause
burns. So, that's the E3 the E3AF. So, when looking at at transactions that call that selector, we can see that Okay, let's debug this Let's debug the transaction. Here's the hash. And when debugging that, we can see that Okay, that's a burn as we already knew, but that's the burn. We have the NFT ID there. And we can see that when that's burning, we are getting ETH back. So, okay, perfect. So, we know that people they send ETH, they get stETH, and then they send they send stETH to that address, they get an NFT with an ID, and then they get that NFT, and they burn
this NFT using this selector to get that ETH back. So, we found the whole the whole loop. Like, we found how we need what we need to do to get our ETH back. So, let's try to do that. Uh here pretty standard. Uh we're just going to impersonate the the user with Envy or something like that. And then we can just approve one stETH, we can deposit one stETH, and then we can get the NFT, call redemption, and get our ETH back. But, when calling redemption, what happens is that Okay, so here is the cast call. We're just calling that address that we that contract that we found. We're adding the selector that we found in here. And 139412
is the NFT ID that we just created. But, when calling that, execution is reverted. So, why is that? We just proved that the NFT is the thing to do to burn. So, let's take a look at the other two events. Let's go back to this graph, and let's take a look at the other two events that have They are emitted by that contract. We can see that we are looking at a 7-day window period, but we have eight events of the bottom two. Uh they are pretty similar and they're always the same transactions. And but let's look at the first one and we can see that on the top on on the events in there, we can see that
it's a very simple event with just two fields. On topic one and topic two, we have two numbers and we can see that 139266 and 139 310. And that's fairly similar to our NFT ID. So, when we start looking at all those eight events in the our window, we can see that this is a batching call. So, every day every 24 hours someone one of those senders is going to send a transaction that's going to call initial batch and final batch and they are increasing. So, we need and we try to we have our NFT, we just need to make sure that have as a batch with our ID in there, right? But how
that would usually work is that every day someone would call this and have the new batch. But there's no team anymore. There's no one running this. The whole team disappeared. So, what we do? We cannot just wait another day as we usually do. So, let's test. What can we do? Going one block before the last batch, I'm just going to try to cash out the NFT. So, we can see that the last batch was from 139266 and we just going to go one block before that and we're going to try to cash out 139267.
And when we try to do that, it fails. The batch is not published yet, so it fails. So, let's try to get one random address that we control and send a batch using that address. We try to do that and it also fails. So, we cannot publish a batch. It's a permission thing. So, what we do now is just try to let's get that address to publish the batch that's accepted and after that's accepted, uh we can claim that NFT, and now that works. So, what we can see here is that we're just trying to send the exactly batch as using using another account. So, 1 2 3 4 5 6 7 8 9 0.
And that's reverted. So, who are it's permission who can send those transactions the the transactions for batches. And that unfortunately makes Lido blocked. We got so far we make it we were able to find how we can mint the STETH. We were able to find how we can create NFT, and we were able to find how we can burn the NFT, but it's permissioned when the NFT is allowed to be burned. So, every day there's a batch that increases the ID, but we cannot send that.
So, yeah, we cannot get out from Lido. And here are the full results with all the other protocols. So, we can see six of them were blocked. I could not get the money out. Lido, EthLend, Maple, Falcon Finance, and Kelp. I got a partial exit on Aave V3 and Spark. Some of them are also hard. Uniswap, Curve, and Pendle, it's possible, but it's really hard and it's really hard to do. You need to spend a lot of time analyzing a lot of transactions to be able to figure out what you need to do. And some of them were really clear exits. Morpheus Sky, Rocket Pool, Compound, and Fluid.
So, some recommendations here for the protocols, like what can we do to make these protocols easier? So, if the thing disappears, if something goes wrong, the company goes down, like that users are not going to get impacted. So, the first thing is that we should add a fallback to every privileged step. So, one thing that I always try to do on when doing this test is like, okay, no one is publishing the batches. If what happens if I wait 1 week, 1 month, 1 year? Can I publish a batch after after that? And most of them were not. But that's something that we could do to improve this protocol. So like if no one publishes a batch in 7 days, all right, just accept any batches that anyone publishes so people can get their money
out. Uh use the standard functions. Uh some of those protocols that I could exit today, it was really easy because the functions were called like just exit or withdraw or redeem. So you could just guess the name and that's what work. Uh make stuff with just one call. Like a lot of those protocols, like sometimes you need to sign two or three or four transactions to get out. Uh not four, but two or three. And that's just makes things a lot harder to do when you don't have documentation. And run the locally test before you launch your protocol.
And for the users, uh try to ask like when you're depositing your money on any protocol, like how who has to act like who has permissions to enable you to leave to get your money back. So also check liquidity. Some of those protocols that I was able to exit, like I was doing that with the 100 largest holder. And I one of them consumed almost 95 95% of the available liquidity. So that guy was able to exit, but not everyone was able to would be able to. If the protocol went down, like not everyone was able to get out.
Uh if you can, like just keep your deposit transactions and keep the contracts that you're interacting with like handy, that makes things a lot easier. Be careful with scam tokens address poisoning and all those scam airdrops. Like they're everywhere. All almost all the addresses that I checked were affected by that were were tried to attack it with that. And run your own node. Like you're always going to need to do a lot of calls and most of the public nodes will not allow you to do that or really limit you hard. So run your own node with the full archive, that will make sync a lot easier.
So, yeah. Thank you. I'm Diego. I work at Amul Scripts. Check it out. Check us out. I'm Diego one on X. So, I'm happy to answer any questions. Thank you. >> Okay. Okay. Okay. Great. Let's move on to the position for answering question. Some say it's located here. Diego, come come by. Come by. Okay. So, I was listening very carefully. You did a terrific job of analyzing this hashes.
But the first question that we have is why correlate correlating calls with events, etc. instead of simply analyzing smart contract code. >> So, that's the idea, right? Like you don't have the code. Like you don't have the block explorer. You don't have Etherscan. You don't have anything like that. The only thing that you have is the chain. So, you cannot get the the smart contract code directly from the chain. I like my protocol could publish that, but yeah, how do you find that? So, in this test like we didn't have any code. We didn't have anything.
Just the chain. >> Okay. Yeah. Well, with this assumption, I guess you will have to look at the hashes. Let's quickly move on to the next question and well, I find it interesting. Protocols aside, does Ethereum itself passes walk away test? >> I mean, that really depends like what's the walk away test for Ethereum? Like you already have ETH in your hand. Do you want to convert that to fiat? So, I guess not, but I yeah, it depends on what what what are you trying to exit? Like what's your money? If it's what USDC, no. But Ethereum, like that's already the final step. Like that's the final
goal, the final asset. >> Okay. Um up next, how important is it for Ethereum to have built-in source code verification for smart contracts? >> All right, that's yeah, that would make things a lot easier. Like if we had this embedded into Ethereum, like you don't have to go there and analyze uh the hashes, analyze uh the logs and all that. Like you could go there and just read the source code. That would be amazing. Like that would be perfect and it would make this so much easier and people in the future would make it a lot easier and safer for people to access these protocols.
>> Would you be brave enough to draft an EIP for that? >> I can try. I can try. >> Okay. Okay. Good. Good. We have an EIP draft getting prepared right here. Next question and it is closely connected to what uh we already discussed. If we assume a situation when there is no UI but docs or at least source code of the smart contracts available, would it still be the same pain to interact with the major protocols or would it improve the situation? >> So, it would improve a lot. Like most of these protocols mm some of these protocols they are they all have like some kind of uh emergency exit or emergency stuff that is like one other way that you can exit
if something goes wrong. But the issue is that I could not find one of those by just looking at uh transaction history. Most of those are not even used that often. So, yeah, having docs would make this a lot easier. You don't have to keep guessing contracts, guessing selectors, or looking at opcodes. Like you just uh go there and read and see what happens. So, as the previous guy was telling, like if you have the docs uh in there well-documented, like you don't need a thing anymore. Like if that's is still available, that would make things so much easier.
>> Yeah. >> Okay. And the final one. Oh, it looks like we have someone from Lido in the room. Okay, Lido it's not even a question. Jesus Christ. Lido withdrawals are finalized by the Oracle and without the Oracle nothing would work in a staking protocol. Fair enough. Whoever submitted that, fair enough. Okay, and that's it with the questions. Diego, thank you very much and