Security at the sequencer level
EthPrague 2024 · 1 Jun 2024 · 27:37
Martin Derka introduces a sequencing protocol for a rollup that is enhanced with security solutions designed to trap hacking transactions at the sequencer level. The technical talk at EthPrague 2024 elaborates on how the protocol is implemented and discusses related questions for Layer 2 networks, including censorship resistance.
Speakers
Topics
From EthPrague 2024, hosted by ETHPrague.
Transcript
[Music] your yes yeah you have the screen all right so we We are continuing with our schedule on time uh the next talk will be from Martin derka and he will be talking about security at the sequencer level uh please join me welcoming Martin with a big round of
applause all right hi everybody uh my name is Martin I'm very happy to be here I love coming to eth Prague uh I love showing new material in here uh I'm from zerit uh so some new material here for the first time ever I will be showing you security implemented at the sequencer level so before I do so uh I would like to introduce zerit uh we are a new zero knowledge rollup uh we are fully evm equivalent uh and as I said we bring security to the uh sequencer so before I go deeper I should probably tell you a little bit about the terminology that that I will be using and explain what rollups are okay so let's take a look how a z rollup Works in general in a normal rollup not only ZK rollup you
always have a chain that you spin up and that chain runs a little bit faster than ethereum you configure it so that it produce blocks very quickly right so that those blocks are bigger and that chain has something called sequencer sequencer is a service of the blockchain that is responsible for organizing transactions into the sequence right so this sequencer receives transactions from the user and every once in a while when it has enough of them it has enough of them to produce a block so it poops up a block and it append it to the chain and then we have another service that is waiting and when it has seen enough blocks it takes the state rout of the blockchain of that L2 and it submits it into some smart contract on an L1 and
that submission is done in two ways depending on whether you're a zero knowledge rollup or an optimistic rollup if you're an optimistic rollup it will be this kind of a trust me bro principle you know we roll it up and you have a period of time where you can check challenge something when you are a zero knowledge roll up when you are rolling up uh you are submitting a chain that is equipped with some sort of zero knowledge proof that removes any kind of trust it's mathematically proven that that transition was executed correctly okay so this is the principle of a rollup now zerit does a little bit more and it does a little bit more on that sequencing level so in zerit we also have our L2 chain right it's sticking a little bit faster than ethereum our block time is 2 seconds uh and we have a
sequencer the sequencer again is receiving transactions from multiple sources from the users and when it has a transaction it doesn't right away included in the block what it has available is what we call an Oracle and it asks this Oracle hey is this transaction okay for being included in a block meaning is this transaction benign or is it here to hack something is it going to damage some of the users residing on this chain is it going to drain your favorite lending protocol or something like that and if the Oracle says yes this transaction is safe nothing changes the transaction gets included into the next block and if the transaction is not safe then instead it gets quarantined and doesn't get included into next block
okay and the rest of the process is the same once we have enough blocks uh we roll them up into smart contract on L1 uh and because this is circuit this roll up will come equipped uh with uh zero knowledge proof so let's see how this actually works in practice ice because we have this uh implemented I will be demonstrating this on an example of a hack which is based on some economic manipulation so let me first explain how this hack actually works okay so first of all we will have one smart contract I will be calling this smart contract the victim pool and the purpose of this smart contract will be to hold some erc20 tokens and sell them to whoever comes for the exactly same price as they
are currently being traded on for uh on Unis swap okay so let's configure this pool so that it holds for the sake of a practical example 30 million tokens so on top of that as I said I will need Unis swap so I will have a Unis swap pair and that Unis swap pair again for the sake of an example I will load with liquidity where it will have 30 million tokens and 30 eth so Unis swap is willing to sell me 30 million tokens for 30 e and then we will have an attacker contract act whose obvious goal is to purchase tokens from the victim for price that is much lower than the market price much lower than the fair fair
price and finally because I will be U manipulating some markets on Unis swap I will need a flash loan provider so flash loan provider will have the purpose of uh or the uh possibility to give me a loan of some amount of tokens here again I will have 30 million tokens for the scope of a single transaction and if that loan gets uh repaid at the end of the transaction the transaction will become part of the chain okay so this is my setup those are the four actors that will that will be participating in here so let's start hacking so at the beginning what the attacker does is that they will come and say hey dear flash Lo provider you have 30 million tokens uh I would actually like to borrow them okay so this is the
first step the attacker Bor borrows 30 million tokens and the state that will be recorded as an intermediary state of this trans action on chain will be that attacker has 30 million tokens and the Flash Lo provider knows that somebody owes them 30 million tokens okay so then the attacker has those tokens and they say hey I will take those tokens and I will sell them on Unis swap to drive the price of the token down right so they come to Unis Swap and they say hey here's 30 million tokens give me all the ether that you are willing to give me for that so that will double the amount of of tokens in the Unis swap pair it will drop the amount of ether in that Unis swap pair and that ether will go to the attacker so what it will
mathematically work out to is that the attackers now hold 15 e they have no tokens but the state of Unis swap is that they have 60 million tokens that they are willing to sell you for 15 eth right so that means that Unis swab is currently selling 1 million tokens for much less than one e which was the state at the beginning okay so this is already wrong therefore the attacker can come and say hey victim pool uh please do sell me some tokens of yours for the price that they are currently being traded for on Unis swap right and because we want to be smart about it we are not going to buy all the tokens from the victim pool but we are only going to buy 10% of those tokens okay so I'm
going to buy 3 million tokens from the victim pool and that will cost me roughly 0.75 e so way below what would normally be the fair price so this is the change victim pool now has 27 million tokens and the attacker has 3 million tokens and still nearly 15 eth right 14.75 well now we have more erc20 tokens so we can do this again right we can go to Unis Swap and say hey Unis swap here I will give you three extra million tokens to drive that price of the token even more down so we do that and we will end up with Unis swap holding 63 million tokens they will be selling that for
roughly 14 eth but the principle is now Unis swap is selling 1 million tokens for one much much less than before uh than for one eth and the attacker uh contract again has no tokens and little bit of extra e and then rinse and repeat right so we go to the victim and say hey give me 10% of your tokens and it will be even cheaper than before right because we drove the price down and again we have acquired some tokens the victim has much less tokens and we will keep doing that we will keep going to Unis swap keep selling those tokens keep driving the price down and the point is that with every single iteration where we do this there will be one extra much
much less in here and the victim pool will be losing tokens and the attacker will be gaining tokens okay so this is roughly what is happening up until the moment when the pool is sort of almost drained Unis swap at that point will be selling the token for no almost zero price because there will just be excess of liquidity in it right victim pool will have almost nothing it will not have received the fair price in ether for uh for uh the tokens and the attacker will have all that ether that it collected for selling the tokens on Unis swap so that will work out to roughly 17 eth well and now it's time to close the hack so attacker comes and
they will buy all the tokens back from Unis swap we have 17 each right we will 100% be able to buy you know the original 30 million tokens that we sold to it plus all that extra stuff that we have sold during the individual iterations on Unis Swap and Unis swap will be brought back to balance so they will have probably 30 million tokens for approximately 30 e well now since we have all those tokens we can close the flash loan we can repay right so we send 30 million tokens back flash room providers is uh Happy and the final result is this attacker still holds whole bunch of tokens victim pool doesn't have any tokens left but it
also has you know probably no eth left right uh or it received no eth for it flash loan provider is Happy the loan has been closed and Unis swap is Back in Balance so victim pool is damaged attacker is super super happy so now I have a demo for you I'm going to do two things I've scripted this entire house hack so I created a smart contract that represents the pool I created smart contract that actually hacks that pool and I will be showing you how those smart contracts look and how that execution looks on a local simulation in hard hat on my laptop and then I'm going to show you how this would look on circuit testnet which currently has the sequencer level
security embedded so it will be discovered and it will be quarantined okay so I'm going to switch into my terminal and I'm going to ask for some assistants Perfect all right let me see how this works I will make it larger all right there we go perfect all right so uh first I should actually show you that smart contract that uh implements the exploit right so this is my exploiter I said that we will need
some references to flash loans to Unis Swap and to Ether which in the case of uh Unis swap is called we it's the wrapped ether so those are some variables or attributes that I have in here then I have a Constructor and then I have an entry method into uh the attack it's called initiated flash Loan in here I'm going to tell the smart contract how much of the tokens I would like to borrow from uh from uh the flash loan provider and who is the victim that I would like to hack and I'm going to make a call to the flash loan provider saying hey please give me those tokens that I have requested now the execution is going to get transferred to the flash loan provider the flashl provider is
going to transfer those tokens to this exploiter smart contract and it's going to in revert call back this function called execute operation okay and inside of execute operation I do in a loop for good measure 20 times exactly what I've just described so I'm going to sell all the tokens on of Unis on Unis swap so here you can see that I'm reading my own balance for this particular smart contract then I'm going to approve these tokens to the Unis swap router and then I'm going to tell the Unis swap router hey please Swap all these tokens that I have this is this balance for all the e that you're willing to give me right so
I sell all of them and then I go to the victim and I say hey victim how many tokens do you have okay how much e would you want for that and I'm going to buy those tokens from the victim I'm actually going to buy only 10% because I'm dividing the balance by 10 in here okay and that all happens in the loop when the loop ends in here uh I'm going to come with my ether back to Unis Swap and say hey Unis Swap and I'm going to put it higher Unis swap please uh give me all the tokens that you are willing to for all this ether that I currently have and then at the end I'm closing the flash loan okay so this is the transfer now I have all of that set up
in a test so test so this is a standard hardhead test uh in mocha so the setup of the test is that at the beginning I am uh defining some constants those are those numbers that I've told you I everybody to have roughly 30 million tokens so I Define my tokens I have some log statements for uh nice output during execution and then I start deploying I deploy an erc20 token that will be my mock token that I'm going to hack I deploy we because this is what Unis swap wants I deploy a factory because the factory is needed to create the Unis swap pair then I deploy the router so that I can actually trade
on Unis Swap and uh then we deploy flash Lo provider and we load this flash Lo provider with 30 million tokens okay I'm going to scroll up this is where we are transferring tokens into the flash loan provider then we create Unis swap pair that trades these tokens for we and we are going to provide liquidity to Unis swap so we are going to approve the token then we are going to create for ourselves some we then we are going to approve we and uh we are going to add liquidity to the Token pair and then finally we're going to deploy the victim so here is the victim pool the victim
pool will be again loaded with some erc20 tokens and finally we are also deploying the exploiter smart contract which is the Smart sound oh all right h yeah all right thank you uh so finally we are deploying the exploiter which is the contract that I've already shown you right and uh that is going to uh hack the victim the hack itself is then in the test unit in here and the hack itself is on this one line because we are really talking about a single
transaction right so we are calling that entry function initiate flash loan with how much we want to H uh borrow who needs to be hacked and then we are just waiting for this transaction to get mined finally some log statements again so that we get nice output so if I now go ahead and execute this on my local network it's going to look somewhat like this so scrolling up we have 30 million tokens uh and 30 we that went into Unis swap pair so exactly as I said 1 million tokens for one eth uh and then we have some uh logging that you could have seen so exploiter right
now didn't receive any tokens right it starts with zero balance victim has 30 million of tokens flash loan provider has also 30 million of tokens and then the transaction that uh uh exploits the smart contract actually launches so I have instrumented my smart contracts with some log statements so those are 20 logs that are being printed in those individual iterations when I am purchasing tokens from the vitim so as I said in the first uh in the first iteration we are purchasing 3 million tokens for roughly 0.79 e in the next iteration 2.7 mil for 0.64 and you can see that in every single iteration there is actually that you know uh amount that I'm purchasing dropping because the pool
is getting drained and I'm purchasing it for less and less and less eth because the price of those tokens on Unis swap is also being driven down when the exploit comp completes let me see if I can actually move it up for you there we go when the exploit completes uh this is the final state so the flash loan provider was satisfied it received the loan back right the victim got totally screwed because they do not have 30 million tokens anymore they only have 3.6 left notice that this decimal point is actually moved right compared to the other ones and the exploiter now has balance it started with zero and now it has 20 million tokens right so this is a
justification that this hack actually works that I you know did not make it up how it should work uh you are seeing it now what I have next for you is actually a video of how this thing works and plays out on zerit now I'm hoping that this is going to be big enough for us let's see uh hopefully there we go so uh I've deployed all those smart contracts on zerit and execute did exactly the same hack so here you can see what I'm doing I'm going to play this at the beginning uh at the beginning we are deploying right so I am deploying from this
account DAC uh first the mock token then after I deploy the mo mock token I deploy we after I deploy we I'm going to start deploying Unis swop so first you get the factory after the factory you get the router after the router we will be able to deploy The Flash loan provider then we are going to use the factory to create Unis swap pair then we are going to log uh something and load that pair with liquidity we've added liquidity to Unis Swap and now we are going to deploy victim and that should be it okay so this is the first step this is the setup now I'm clearing my terminal and I'm
going going to deploy the attacker so deployment of the attacker that's going to come from a different address um so nothing special this is my exploit orchestrator that's the address that I'm going to uh turn this back a little bit this is the address that I'm going to be exploiting from this resolution is not good okay I'm not going to turn it back so there is an exploiter contract deployed now uh what I've created for myself in here are two auxiliary scripts so because we are going to be quarantining some transactions it wouldn't be a good experience for the users if they
couldn't know whether their transaction was not mined because they had you know some issue with the transaction or whether it was like underpriced in in terms of gas and it's still like waiting for being processed right or whether it was actually quarantined so what we have created are Uh custom RPC methods for GU uh zeror get quarantined which returns for us the content of the quarantined as it currently is and uh I have one more uh method it's uh is quarantined Zer un underscore is quarantined which takes one parameter it's the hash of the transaction and that tells us whether the transaction has been quarantined or
not specifically so it returns true or false so now I'm listing the quarantine you can see that the result is currently empty right and I am going to run the exploit so now the exploit starts on zerit and you are going to be able to see that we've logged something and we are launching the exploit but no output is coming out why is no output coming out well because the transaction is actually not getting completed it's not getting mined so in my scripts I'm going to show you that uh that exploit script
um what I have in here is this line so here I'm launching the exploit here I am waiting for the transaction receipt right that gives me back the hash and here I am waiting for successful inclusion of the transaction uh to the next block where it would tell me hey this transaction was completed or this is where it would fail so this line actually never completes because we are not sure what's going to happen the transaction gets quarantined right so the attacker is just waiting up until you know you can see this control C in here I decided to kill the command because now we can actually double check what happened and we can
list the quarantine and our quarantine is no longer empty I don't know if you guys can see it but the hash of the transaction is zero X 785 in here uh and then if I query uh the uh other script so here I am filling in this hash of the transaction into uh this parameter uh if you've seen what I've pasted for the first time I actually screwed up I pasted the wrong hash from my uh clipboard uh so now I'm grabbing the proper hash I'm fixing it uh I'm going to put the right one in there and we're going to query it again and you will see that this actually returned through this time okay so this transaction is now quarantined so this
is the end of my demo thank you a lot uh back to the slides so we have seen that zerit has successfully captured this transaction and quarantined it obviously you know for non-technical users this will be also displayed on the Block Explorer so this is a screenshot from our staging environment From the Block Explorer how this is going to look when we launch our main net and right here if you can read this uh first transaction this is actually the one that starts with 0x 785 that's the one that was uh quarantined so how does it work in the background the implementation of zerit is uh based on gu uh so uh gu maintains some very creative naming for pools of
transactions that it maintains so it puts all the transactions that it receives from the users that are are properly signed in something called q and then it has also something called pending Q where it moves the transactions that are ready for immediate inclusion uh for the next block for example because they already mean the nons rules and so on so there's some validation that happens in between and this is exactly that moment when we hit the Oracle and we say hey should this transaction actually be moved to the pending queue or should it not be moved to the pending queue and go to the quarantine instead and for us quarantining transaction essentially means that we put a flag on it and says hey do not ever or you know up until some other conditions are satisfied move
it into the pending que so uh some early experiences with this zerit is currently on testnet uh there are not so many hacks that happen on test net right so a lot of this is uh based on our testing environments and various simulations uh but the very obvious question is how performant is this at the beginning of the talk I mentioned that zerit block time is 2 seconds right so if I you know needed 10 seconds to analyze a transaction that would actually again provide very terrible user experience so the bottom line is that that our oracles are performant enough that majority of transactions can be analyzed under 1 second and some of them you know can take up to two seconds so the bottom line is we actually using these particular oracles have sufficient
bandwidth through paralyzation to accommodate the blockchain traffic at the two second block time which is great uh you might you might be asking what happens with those transactions into quarantines I was getting a signal that you know I'm slowly running out of time so I actually have a different talk uh it's from eth Denver there is a YouTube uh recording of it so please watch that uh if you want more details about implementations and considerations for the sequencer level security we also have a paper on archive so if you Google my name and sequencer level security it will definitely pop up otherwise here is the archive uh link other question that comes up is if this can suffer from denial of attack uh yes uh well uh the
yes you can attempt but no you will not be successful there is a cost so that there is some civil protection there again deferring this to the paper uh how strong these oracles are vary we have you know the privilege of having the transaction history of all the evm chains available on those chains right so we actually back tested those oracles and then trained them and uh they are very strong there are some hacks that I'm listing in here that were caught by these oracles and yeah the bottom line is the oracles are very very strong uh can it be decentralized yes again uh deferring you to the paper can we work with multiple oracles yes deferring you to the talk from Denver
and when Zer mayet zerin mayet where this is going to be available for every single project and every single user on the network is coming in summer of 2024 as I said we are a zero knowledge rollup so we are also right now running a kzg ceremony so if you would like to contribute to our trust uh and The Trusted setup please get in touch with us on Discord on telegram anywhere we will very gladly include you and that's everything that I wanted to tell you so uh yeah this is zerit this is zerit uh sequencer level security if you like zerit please come and build on us thank thank you very much Martin That's
precisely on time and with a live demo that went Flawless so thank you and