 Thank you very much, Francie, and thank you, Akus, for the first talk, actually made my life much easier. So I want to also make your life easier for the people who are in the room. We actually have also a formal verifier, and actually you can try it as we speak now. It's actually implemented and hosted in Amazon. So what you can do at the moment, if you're not our customer, we don't let you change your code, but you can change your spec. And I encourage you to actually try that. It's actually a beautiful demo, which was put by Anastasia and Rit from our team. And actually, this actually shows you that you can actually, it says actually fail to access my camera, but you can see me, right Francie? Yes, we can see you fine and see you fine and see the slides. All good. Wonderful. So what we are very happy in this space, and we hope this will continue, we are finding terrible bugs in this space, and terrible bugs in smart contracts, and actually I'll give you a little bit hint of how we are doing it. So wait a second, this doesn't move now. So who are we? So we are, we are actually a team which is located in Seattle and in Berlin in Tel Aviv. Shelly Grossman, James Wilcox, John Toman, Norito, and Alexander Neutru is actually here in Berlin. We are open-eyed with a security expert or a Pistinair, Anastasia Fedotov, and Thomas Berandi. And what we are trying to do, we are trying to formally prove like the previous tools that they called satisfy the specification, but as I said, we are equally interested to actually find bugs, and actually that's the biggest value of our technology as part of the CI CD, is actually find bugs. And just to mention, we had the previous talk, Interactive Term Prover, these are very powerful tools, they are agnostic to the programming language, they have even completeness. And the previous talk we had also by Christian, and we hear tomorrow about SMT Checker, this work at the Solidity level, also the Solci Verifier, and the very sold by Microsoft. So what's interesting about our tool operates directly in the EVM code. We think that this is very good, and in fact, I'll show you. And the second thing that we do in Sertora, and I'll talk about it in the second part of the talk, that we are actually implementing clever static analysis that actually can recover interesting information about the EVM code, and this actually improved the utility of the SMT. So we see these as two complementary technologies that work well together. So what do we build? We build this product that we call Continuous Code Verification, it's very similar, and you see it in the demo, it's very similar to what Anku shows in one way, in the sense that you give the customer a code, but we actually write in a different file, we write a specification, we write a property that says what are the invariant, what are the rules that must be obeyed, and then we feed it to the tool, which is hosted on the web, it's actually either can give you a formal proof, or it can actually give you a test case, and that's actually a very valuable test case that show you input that violate the specification. So the interesting thing about that, that we think that specifications are hard, but once you write the specification once, when you upgrade your contract, or you move to another version of the contract, we can check that your code satisfies the specification, and we have already done it with few customers, which integrate our tool into the CI CD. So there are unique aspects of that, so one of the things that we say that we decouple the specification from the code. So we don't write these loop invariant in the code, we write them outside the code, and we write them in high level in the sense that we want to make sure that we guarantee certain properties that outside user care about, like for example, inverted operation, the bounded supply that I'll show you later, maybe you want your transfer to be additive in the sense that if I S transfers to D, and it first transfers X, and then it transfers Y, then if it transfers X plus Y, it should be the same. And interestingly, we can check this property and either prove them, or even more interesting find box. And the other aspect that is unique about our approach is that we tackle the low level EVM program. So this has some pleasant benefits. So basically, we want to make sure that you don't need to change the spec when you change your code. And in fact, in some cases, we show that we can use the same spec for different projects. And another thing which is interesting because we operate on the low level code, we can catch more errors. So this means that we can actually catch errors that are not actually caught on the source code. And we verify the actual program which is being executed. So for example, if the Solidity compiler generate a loop, if the Solidity compiler generate anything in fact it does, if the Solidity compiler generate tricky memory operations, we can actually check them. So we see ourselves as a checker that can be executed after the compiler. So I'll give you a very, very simple example. And this is an example which is in the demo, but there are other examples which are more tricky. So this is a very, very simple property that any ERC token should satisfy. And this is actually given by Shamik Islam, which is the head of security at Coinbase. So when they list tokens, they want to make sure that nobody should be able to mint unbounded number of tokens. So formally some kind of environment that says that the number of minted token is less than the paid defined amount. So let's see of a very nice team, which is the Make-A-Dow. And this is a team which implement an inverse auction. So what is an inverse auction? You start by some kind of a bid, which is high. And then you have different guys, Alice Bid and Bob Bid. And since Bob Bid was the smallest one, then at the auction at time, after the closing time, basically the number of bids, basically Bob will get the bid, and the total number will increase by Bob's bid. And this is a very nice behavior. But what happened? We run the tool and we run actually the test version of the maker. We just run it through this bounded minting supply. And basically what it happens, it found out that if you have malaried, and malaried bids very, very close to the max. And nobody else bid it. So after the bid expiry time, at the close operation, basically the total supply is increased by malaried bids. And this is actually something that you can execute now with our code. We can check it. You can write this back and check it. And in fact, it's one of the examples on the demo. So this is exactly what will happen in the demo. It will run on each function. And you see it actually, it operates on the EVM codes. You see some data about the EVM. And what it tells you, it tells you that all the functions satisfy this rule, but the close can violate it. And it gives you the test case. In fact, it gives you the test case that actually show you that it has this violation. And once you fix the code, it will actually show you that it's actually correct. So how does it work? Well, how does the Satura Prover architecture work? So what happened is that we have the first part is something which is very unique in this space. We have a decompiler. We have something that takes the smart EVM code and perform clever analysis. And actually it will perform more. This is actually what John has implemented in the Seattle office of Satura. We are actually getting this high level intermediate representation. Think of something like Yule and maybe more that you can actually extract automatically from the EVM code. This we feed to what we call verification condition generator. So verification condition is not like the VC that you think it's what called the VC informal method, which is basically a method that converts into a formula like we've seen in App Store. And this takes the rules which are form outside and it takes the intermediate representation. And from both of them, it generates this constraint, it generates this verification condition. And we feed them to existing constraint solver. We are operating directly on the SMT level. So we can feed it to different constraint solver, the whole public domain and great and complementary. And these constraints solver either can give you a test case, which actually show you the actual violation, or it can actually give you a formal proof of the rules that hold on all inputs. So this is a very, very simplistic example. I'm only showing you like kind of absurd code. You see this transfer function and you see some rules that says that the balance before is equal to the balance after. And you see that there are these constraints for each statement in the code. We generate a mathematical constraint which emulates the semantic of that. And we also take the invariant or the rule and which we generate it into the question that says that you want the SAT solver, you want the SMT, the model to find a solution to this set of constraints. And each of the solution to this set of constraints, it's represented back. Okay, so basically you feed it to a constraint solver and the constraint solver actually gave you a simple but interesting bug that if you're transferring from an Alice to itself, then in fact this invariant can be broken. So it gives you some kind of an edge case and once you fix it, it can give you a proof. So I want to talk to you about the EVM, which is the interesting part of this talk, which is sort of what we do technically. So I took a very, very simple example. It's the banking example, which is also available in the demo. And it's a very, very simple thing about it like ERC or maybe even simpler than ERC. There are functions like deposit transfer as well. And remember, you see in August talk that basically he is handling the solidity, but we are not tackling the solidity. We are tackling the EVM and this has some very interesting consequences. So what's going on in the EVM? So the EVM, you basically have a flat memory. So basically all the local variables and fields are all actually hidden and the operations are low level operations. So even if you select a field, it becomes a bitwise operation that we know as SMT solver, that's very, very difficult. So you make the task of the solver very difficult. And even whereas the control floor and the procedure are really hidden and even the arguments are hidden. So this makes the life of the verification or even somebody was investigating this code manually, very, very difficult. So this is just to show you what happened. It's an output of our tool. So this is one of the stages of this decompiler. And I'm sure you don't understand what's going on here, right? So basically what happened is that these are nodes that represent the EVM instruction. You can't read it and so do I. But each of these, it represents some kind of execution of the EVM. And there is an error if one instruction can be followed by another instruction. So you see that these are in one thing that you can see here, which is kind of weird that in the EVM, it's all kind of spaghetti, which actually there even the procedure structure is lost. So for example, here is this deposit, if you believe me, and I will not be able to prove, but this is the deposit part. So this is a part of the EVM, which is the deposit. Here is the withdrawal. So they're very, very tricky. So reading this code or running static analysis or formal verification of this is very, very tricky. And even if you take this small function, this transfer, which is part of the bank and you even look at that. It's a solidity level. It's very, very clear. But look at this instruction. So basically the access to funds, funds message sender as part of the require. This looks very, very simple in solidity. But guess this is how it's generated in the EVM. There are in fact 21 instruction. You should ask Christian later, but there are 21 instruction here. And this 21 instruction, they manipulate the memory and the stack in a tricky way. So what's actually is going on? This funds message sender is actually mapped as a hashing function, which is actually you can cut the message sender and the slot of the fund. And this is executed by means of increasing and decreasing the stack. So you see the first instruction, it puts zero in the stack. The second instruction duplicate. Now we put message sender. Now you put this value cleaning. You put another zero. You put the value cleaning again. You put this duplicate. You put this 20 years, so now it's 32. You put this add, you put the swap. You do this store level. And now there's this 32. You add the 32 to get 64. You put this zero. I'm sure you lost me by now. There is this hashing thing. Now there's zero, there's drop, there's load. Eventually trust me or trust Christian, it actually gets you the right solution. But if you want to read it or run formal verification here, it's very, very tricky. There are a lot of things here which makes SMT even harder than it usually is. And SMT is a very, very hard problem. So this makes life of people hard. And this is actually where static analysis would be useful. Okay, so what do we do? So beside using SMT techniques, which are wonderful. We're also using other wonderful techniques and developing our own, which are called abstract interpretation. So there is a well understood theory that says, how do you automatically find environment about your program? And we do that at a low level program, but you can actually execute these kind of things at a high level program. And these, they prove some kind of absent, silent overflow. For example, we can actually implement something similar to safe mass, but not dynamic. We can actually automatically find something that was similar to our without even calling the SMT. And this gives you some kind of a sound and potentially incomplete reasoning, but it's not so bad for us because we can actually run the SMT. And from a computational point of view, it's actually sidestep the problem of undecidability. So what's going on under the hood of this tool? It actually does this sidesteping of undecidability and proves properties of your program by doing this abstract interpretation. So what's going on? You take the state, you take the set of state, and you over approximate the next state, and then you over approximate the next state, and so on and so forth until you reach what we call a fixed point, a point where the analysis stopped changing. And at that point, if we actually separate the good state from the bad state, we will automatically be able to find environment about your program. And this happens if your program explores some kind of locality property. And if they don't, then, in fact, this will give you a false alarm. But so for us, it's not so bad because we have the SMT checker that we can run in order to check whether these are right or wrong. So what we do in this space, we are developing this framework that you can think about it like EVM, like LLVM or SUIT. So these are things that develop academic research project University of Urbana, Champagne, and also McGill University. SUIT is for Java, LLVM is for C. So we are trying to do something similar for EVM, and we are exploring the properties which are unique in this space. And I'll be happy to say more or you can contact John. So we are doing memory analysis. We are doing unused allocation, bound checking. We are doing all kinds of analysis. And actually, it's we are an intermediate step and we are doing more and more. One thing which is interesting that during this process, we are finding actually bugs in the Solidity compiler, we just found one. And also that we can actually reconstruct a lot of the high-level information from the EVM. And this could be useful by itself. So for example, here, I didn't show you all the code, but you see that actually these are the 21 instruction. And you see that the static analysis actually was able to eliminate the stack. So you see there's no more memory here. And in fact, you see that we are able to recover almost the information of the source. And this is useful whether you are doing static analysis or not. So basically, this makes the analysis simpler. I can show you many, many examples that SMT timeout. And this will terminate in a few seconds. And what it does conceptually, it separates the low-level operations, which I executed in a bytecode from the high-level operation that we are proving. And it will allow us to prove stronger in variant. And actually, it makes it more the bugs that we are producing are more understandable. So the compiler, of course, has many usages beside formal verification. This is known, of course, in the community, program understanding, slicing, auditing. For upgradable contract, we can check interesting properties and other things. So that's one thing. So I'm almost close to the end of my talk. And I want to somehow say something about more high-level and leave a level for other discussion. So we are this space. I've been working on this space for 30 years now. So there are actually many interesting techniques in this space. And somehow, I like to think about them as how expressive they are and how automatic they are. And this is a very, of course, I should say this is a bit subjective, but there have been academic articles trying to compare them. So we heard this morning about tools like K, or Coq, or TLA+, they are proof-assisted. And they are very good, but they require laborious effort. I'm just pointing out an academic effort where we did something for academically in the context of IV, where we tried to compare how much effort are in these interactive term-prover. And it's a very, very big effort. And it's even worse in the sense that once you change your code a little bit, you have to redo it. On the other hand, there are a lot of beautiful techniques that develop by many people, including myself, Stani Kanaz, and they are very automatic, but they are limited. And what Sertorah is trying to do, Sertorah is actually trying to be in the middle somehow. We hope, and of course, this is something that has to be judged, but we hope to be, maybe not as automatic as interactive, but is automatic enough to enable you to show everything that you want, and even more importantly, when you change the code, find the box. And also we want it to be automatic, powerful. So we wanna actually achieve both of them. I wanna maybe just sort of to, for you, for curiosity, Verdi is a very nice project by James Wilcox, who is our city always in Seattle. And basically he proved properties of consensus in Cork. And every line of code, every line of the consensus protocol, he had to write 10 lines of Cork. So that's very tricky. Iron Fleet is a project which actually used Daphne or Boogie. And in fact, it's actually also difficult. And what we are trying to do, we are trying to make it very, very small. And I think we have numbers that show that we actually have very, very small lines of at least academically for these protocols. And in Sertorah, we are trying to be even more automatic. And sometimes we sacrifice precision, but other things, but also we are leveraging a lot of interesting properties about these domains. So we are doing something which is very, very specific for smart contracts. So this is my last slide. I wanna make some, we want to make formal verification standard for software development. And the interesting thing is that we think that this domain, and I am of course academic, but now I'm taking a leave because I'm thinking that this is a very interesting domain for this technology. And in particular, we're interested to explore the connection between proof of automation and automatic bug finding. We think that actually there are actually two sides of the same coin. So we don't wanna separately look for proof and for bugs. We want to actually connect them together. And the other thing that we are trying to do, I haven't been able to show you, but you can see our specify language. We have quantifiers, we have hyper properties. We are doing a lot of things that make actually verification at a high level good. And we love to collaborate with the Ethereum Foundation, anybody else. And the sad thing is that we operate at the EVM level. Thank you very much. Thank you. Thank you for your talk, awesome. All right, we have a couple of minutes left again for questions. First the questions in the room, then the questions in the chat. Leo, you want to say something? Yeah, thanks Moli for the talk. I think it's a very nice and special challenge to talk about high level invariance on the EVM level. And related to that, I took a very brief look at the spec language you just mentioned. And I was wondering how do you deal or how do you specify or how do you manage loop invariance in the context of, in the EVM context? Beautiful question. So that's actually something we asked you. It's very difficult for us at the moment. We have a mechanism for that. I think we discussed with you. We have a mechanism for that. What we are doing and that's our hope. And in certain cases, we can infer them automatically. But if not, we have to say something which is specific to the core. For us, usually what happens, for example, if you have a procedure, you have pre and post condition, then it's make it easier because we can specify that the procedure boundary. But you're absolutely right. There are certain cases that actually the source level is something that is better. But remember where we want to be. We want to be for people who change their code and the problem is loop invariant. It's not just a one-time thing. You change your code and every, as you know, every little change of your code, you change your environment. So it's true actually. We are, at the moment, we want to infer. So if you're right, for example, in our specify language, you should see there is this notion of set invariant. But what does invariant mean? It's a global invariant. So basically what it does, it checks that before in every procedure, it checks them at the procedure boundary. But if you want to do them at the loop boundary, you actually have to either infer them or do some other thing. Our tool, by the way, also has the possibility of doing bounded model checking. So you can actually say, explore fixed bound of the loop and other things. And we also, another thing that we are doing with the static analysis, we infer actually interesting loop invariant and I love to elaborate about it. So we can infer quantified invariant. We can infer many things which are very hard for SMT because this is actually my research as you probably know. Yeah, thanks, yeah. We talked about it some time ago and I was just wondering, yeah, how it looks right now because it is a very hard problem. And I personally haven't gotten very far and that's something we're trying to figure how to specify for Act, for example, on the lower level. Yeah, yeah. So we should definitely talk about that. We actually have coming code which will probably contribute open source that does an interesting thing that needs this loop invariant. So I would love to talk to you and of course I will attend your session tomorrow to understand what you are heading to. Cool, thanks. Okay, we have one more question in the room from AP. We can't hear you in case you were trying to speak. Sorry, can you hear me now? Yes, now we can hear you, perfect. Okay, perfect. So my question is regarding the fixed point analysis. Basically, as effective smart contracts even the simple one have a concrete domain of them it's invisible to find a fixed point. So what are you using it for as your abstract domain when you're looking for a fixed point? Yes, yes. So this is actually a question to John but he's sleeping so I'll try to do a good job. So he's adding more and more things as we speak. I think the interesting thing, so you're from this domain, I just don't know how technical to get, but it's one thing that pointer analysis in this domain so we talk about it that there are things that tell LVM and others, but everybody say a lot of bad things about solidity in EVM but we can say a lot of good things. It's much easier for static analysis than many of this domain, in particular memory allocation, actually there are no de-allocation. So basically we have points to analysis but it's very simple and we love to say what we are doing. We have interval analysis and we are adding more as we speak. Then I think about it and we're working with customers and we see the customer code and see what is needed for this code. And we have the SMT always as a backup. So basically you run the SMT. If the SMT does a good job, we don't have to do anything but in many cases when the SMT fails then we actually have to develop more clever abstract domains. And we are thinking of adding more abstract domains to that. We have basically like kind of a framework that we add more and more abstract domains.