# Contract-based soft forks: Coining a term in search of hack prevention

- Channel: [ETHBerlin](https://streameth.org/ethberlin)
- Date: 2025-06-19
- Duration: 28:10
- Watch: https://streameth.org/watch/6854233b90bd41297b6c1cf3

## Description

In this talk we discuss a novel mechanism we call the Credible Layer, which is designed as an overlay mechanism that enables a Blockchain network (L2 or L1) to enable contract-based soft forking. Developers can associate EVM bytecode with contract addresses which adds additional transaction rules  to transactions that interact with these contracts.

## Transcript

Is this working? Okay, now it's working, cool. Okay guys, thank you for having me today. Does this work? Yep, cool. So, today we're going to talk about our mechanism, right? The credit layer. But I wanted to walk you through how we came up to be as a mechanism, what were the goals, what were the origins, and then talk a bit about the mechanism, the architecture, the core, which is the assertions, and I want to generalize it a bit and talk about how you can extend the network, you can build the protocol around an existing mechanism without actually doing the protocol, and what's this overreaching design pattern that we have seen a lot of times. So, our story begins as is usually due with trauma. I was part of the Nomad protocol team. We got hacked, and I started thinking that maybe the hack was not cool, and maybe not all transactions should finalize, right? There is social acceptable that hacks are not something we want to have in our systems. So, further with that simple question, how can you not finalize the hacks on the network? I had to answer three questions, right? Like, first, what is a hack? How do we define a hack? How can we make the definition provable on chain? Because usually the definition is quite complicated. And then how can we incentivize the network to prevent hacks, right? I had these three questions. So, the first answer was, okay, let's take a step back. Let's say we define the hack as an idiom computation, right? A complicated one. Maybe we can't run it on chain. And we say that, okay, if that computation is true, then we say it's a hack. The business logic and the protocol logic diverge for some reason. Like an inverse intent. Then somehow we can prove the computation on chain. That's not very hard anymore. With VKTs, that's a simple problem. And then we can reward the nodes to not hack on the network and penalize them if they do. So, the first idea was a bit weird. We're going to have a consensus attack on Ethereum. We're going to define the hack as a VM bytecode, put it on chain. Then some nodes on the network will run this modified software, and they will not vote for blocks that have hacks in them. So, these blocks will just be reorg'd out, right? They will not become part of the canonical chain. Not a great idea. Probably will receive a lot of pushback. That's a discussion I had on my Telegram. So, probably this idea was unlikely to be adopted. Actually hard to implement, as you have to have two-thirds of the validators. And actually, it kind of nukes the chain UX. A lot of honest transactions would be reorg'd out as well. The second idea, the credible layer. Again, let's say the dApps post rules. We call them assertions on chain. And link them to the contracts. Then the nodes will promise that they will not add transactions on the network that would violate these rules, these assertions, right? We actually only need them to have veto rights. And the nodes will accrue value over time. They get paid, and they get slashed if they break their promise. Quite challenging to do in the decentralized block building environment. So, we actually started to work on roll-ups, right? It seems like a simpler approach. Let's start with something simple. As we say in business, it's like a good beef market. We can prove our use case in a simple, good market, and then we can expand. So, what's the contract-based soft forking? In this system, now, every transaction has two validity rules, essentially. It needs to be a valid EVM transition, but also needs to not invalidate any assertion, right? So, whenever we add a rule to a smart contract, it's almost like a soft fork for this particular smart contract, right? Any transaction that interacts with it now needs to abide by some new rules. Effectively, it's like modifying the STF, the state transition function, for that particular contract. So, here is the diagram, which shows pretty well. So, you know, before, you send a transaction, it passes some contracts, and then it goes, right? That's the EVM. In this paradigm now, you have a transaction, it interacts with some contracts, and then also it has to go through a new system, and also check the assertions for it. A small tangent here. While developing a nation system, as you can think, there's a lot of questions we have to ask. Like, how much does the dApp pay for the service to the nodes, and how? What's the threat model, the incentive design, trust assumptions, proof system, the assertions? Now, how do we define them? What are the use cases? What are the DEVX? What's the performance? And then, for the system, how do you write assertions? How do you test them? How do you submit them? There's a lot of questions, you know, that as you, as a well-developed system and mechanism, you'll have to answer. And the best way to tackle this is to just focus on a small part of it, right? You can't tackle the whole mechanism at once. So we decided to focus on use cases, DEVX, writing, testing, this sort of stuff, and then keep all the mechanism very simple, right? What's the simplest instantiation of the mechanism? And I think this is a very good approach on how to develop a mechanism slowly, as you explore it almost. So in this system, we have two markets. We have the assertion definition market and the assertion enforcement market. Essentially, the contracts don't really need to be the same people that define these assertions, right? We can think of the assertions, security rules, probably the auditors would be better people. So what if we have a system where the protocol needs protection, so it sources assertions from assertion submitters? And then with these rules, it goes to the assertion enforcers, which is the nodes who enforce the assertions and take security from them as well. So we have two parties, two sides, the dApps who need security and then the security researchers and the node who can offer security. The first by helping define the assertions and the second by helping them, by enforcing them. So what's the, you know, it's a very simple flow. The assertion adopter, the smart contract, will deposit some security budget, which is used to pay for the assertion execution, write this off, compute. Then an assertion submitter will submit some assertions. The adopter contract will accept them and then it will start to be enforced. The assertion enforcer now, the node, will filter transactions that it receives that are responsible for adding to the network, to the block, and will exclude any transaction that invalidates any of these rules. It gets rewarded all the time, optimistically, but it gets slashed in case it doesn't fulfill its promise. And we can do that with what we call like a proof of realization, which is a proof that a transaction landed on chain which invalidates an assertion, right? And we can do that after the fact, after the transaction has landed. So after you have the outline of your mechanism, you want to start thinking about, okay, there's like a couple of verticals. What is the goals of the mechanism? What do we call the desiderata? What do you want? And for this mechanism, we decide that we want, first of all, latency, right? We want the minimum latency possible. The mechanism should not add any more latency that it needs to. Obviously we want it secure, right? We want a mechanism that is not easy for a hacker to go around. We want it simple, because simple is secure. And finally, we want to minimize it as much as possible, given all the other requirements. So for latency, we adopted one-of-one security model, right? Every security, every node, every assertion enforcer is responsible for their own transactions. They don't need to have another consensus of if a transaction is bad or good. Every node is responsible for the transactions they add to the network. For security, it's very simple. If the assertion enforcer is honest, it can be bypassed, right? Because the assertion enforcer is the entity that adds transactions to the network. If it's dishonest, then it gets slashed. But also there is social slashing, because at least for roll-ups and for Ethereum block building, block builders are not run by random people in random countries, but there are organizations, right? So assuming that the other builder would like participate in the system, promise to enforce the rules, and then get bribed to allow a hack to happen, that's pretty far-fetched. And TEs here could further help with enforcing their honesty. Simple. The same reason the assertion enforcer is only responsible for their own transactions. And then it's trust minimized because all of this can be proved on-chain. If any party doesn't fulfill its promise, it can be proved. So what are these assertions? They're written in Solidity and executed in EVM, but they're executed off-chain. And because they're read-only, like they read from the state, they don't write, and they're atomic, they're very efficiently parallelized, right? So we can execute a lot of these checks. And the outcome of the computation can be proved on-chain. So we have this very efficient off-chain computation where if we need the pessimistic path, we can prove it on-chain. And this creates a very nice primitive because now developers don't have to express the what. They have to express the what, not the how. They don't need to know how the private key gets leaked or how their contract was upgraded. They just need to know, to define, that they don't want their smart contract to be upgraded, right? And also it's adaptable, can be defined post-contract deployment, et cetera. We first implemented this for the OpenStack. And basically the implementation, the architecture has three layers. First we have the user layer of services, smart contracts, and then the block builder. So very simple. The user submits an assertion to the DA to store them. The DA for now is an external server, but we have plans to minimize trust there. And then when the users go to the smart contracts, they link their smart contracts with assertions on our protocol, which we call State Oracle. And then the assertion enforcer very simply will fetch these assertions from this on-chain smart contract and will enforce them. So on every block, we will execute a transaction and apply it to the state. Then it will take this execution trace and see if it touches any address with associated assertions. It will execute the assertions. Finally, it will decide whether to add a transaction or not to the block. And here we go a bit more into detail about how effectively in this final step here, we call the FileXEDM, we take the initial state, we load the assertion, and then we give all of this data to the assertion execution. So now in the assertion execution environment, the developer has access to the transaction object, to the state before the transaction is executed, to the state after the transaction is executed. It could even have access to historical blocks, a lot of things that actually are not possible on the on-chain EVM execution. But since we do it off-chain, we can do almost whatever we want, as long as it's possible to prove it on-chain if we need to. So we also have designed a way to handle forced inclusion. This is an implementation detail for roll-ups like OPStack or Arbitrum, because the assertion enforcer can't really drop forced inclusion transactions, right? They have to add them. But they can delay them. They can choose to delay them. So what we do is something very simple. We say, okay, if a hack goes through a deposit transaction, the sequencer will delay that. And in that time that we have, anyone can prove on-chain that the assertion is about to be invalidated by a forced-included transaction. And then they can execute a mitigation, right? Which is some pre-configured EVM call that the protocol has defined. For example, pause the protocol. So here we have a decentralized and trust-minimized way to prevent hacks even with forced inclusion. The hack is observed on the L1, a proof is submitted, and the mitigation is executed. And all of that while the deposit transaction is delayed. By the time it goes in the L2, there will be no hack. So the credit layer is a network extension, right? It respects the underlying protocol. It doesn't require any forking. And depending on the underlying protocol, it can be actually slotted very cleanly. For example, with OPE, we have Rolla Boost, thank you, so we can actually slot it very nicely as an external block builder. Or it will require some surgery. For example, in Arbitrum. We work around the protocol, right? And obviously, that's some complexity. But why do we do this? Because we can move independently. We don't need to wait for protocol changes. And this is what I call market-driven protocol innovation. It can also be enshrined, right? After we have proven the market demand, after we have proven that networks, Rolla, Dapps, want this kind of solution, they want these runtime checks, we can enshrine it in a few different ways. For example, we can modify the state transition function. And we can say now that the FTF or the proof system for OPStack, also all transactions need to be EVM compatible, but also they have to respect the assertions. You can modify the fork choice rule and we can say that if a transaction lands on chain, which is a hack, invalidates an assertion, then you can submit a proof and this transaction will be out of the chain. We can even modify the social layer and say, you know, if you want to build blocks for this protocol, you have to do it in a TEE, you have to submit an attestation, and the attestation requires this specific program to run. So there's like different ways you can think about when you're building this out-of-protocol mechanism, but eventually you want it to get enshrined. And I think this is a very important point about market-driven protocol innovation, where you can spot an underserved market that requires a protocol update to serve. For example, here the need we spot was hack prevention. And you design a mechanism that requires just the participation of a few network participants, but it's backwards compatible, it doesn't require a hard fork. It's crude, I know, you have to jump through a lot of hoops, it will not be as simple as you like or as elegant as you like it. But with this, you can prove the market demand. You build this crude version of how you think the protocol should work, and you prove that there is people that want that. And then, after you prove the market demand, you have two options, basically. Both are good. Either you've built a very good product and you have entrusted yourself, right? Congrats, you have a moat. Other changes will not be able to get this network adoption. Or you push for a protocol upgrade. You have proof that people want this protocol upgrade. And congratulations, now you have it get enshrined. And there's a number of examples in the market about this approach, right? We're not the first to think about this extension approach. For example, eigenlayers, symbiotic, right? That's a problem that people, for whatever reason, they want to stake their staked if. What do they do? They build this out of the protocol. And they prove that this is indeed something that people want. Lido, Rocketpool, right? It proves that people want delegated staking on Ethereum. Plusbots PBS, right? It proves that the market actually wants to disconnect the searcher, the block builder, and the validator, right? Out of protocol. Ethereum does not know about that. It's completely out of protocol. But right now, it's how we build blocks on Ethereum. They've proven that the market wants that. Plusblocks. Users want precoms for their precoms. Because it has better UX. Out of the protocol. It works with the OP stack right now. But the OP stack is not aware of plusblocks. Right? It's only the block builders that run Trellaboost. They have an external block builder that has this feature. Or like Bob, for example. Like build on Bitcoin, right? They prove that DeFi for Bitcoin is a thing. That Bitcoin liquidity wants DeFi. And that also people would like to use Bitcoin as a GKE verification layer. Right? So that right now they have to go through weird things with BitVM and all these like very expensive and crude constructs. Because they want to prove that this is a need. And if they prove it then they can push the Bitcoin core protocol development. So we're adopting some of this technology for a better version of that. And this is how we'd like to finish the talk. So we talked about what was the original question. What were the main attributes that we wanted to we need to address. And we came up to a high level visualization of the mechanism of the architecture. We simplified the mechanism to focus on a very particular market that was easier. Which is the Rollups. But we simplified a lot of the things. We found an architecture that was easy for us to adopt first. Which was OPStack and RollupBoost. It was easy for us to slot our solution there. And then finally this will be after we'll prove that the market wants this. We'll prove that this protocol change is something the market wants. And then hopefully we can fit that on mainnet or part of the OPStack or something. And I think this is a very good way to think about how you build mechanisms or how you can upgrade the protocol. Ethereum or Erola protocol. Without actually needing to have political power. Or spend endless time on pushing EIPs. You can just do it in a backwards compatible way. And let the market prove you right. Thank you. Applause Thank you. Yes. Perfect. What a way to close the stage for today. But before we finish this off, we have a few questions submitted by people. And one of them I think is quite appropriate to what you were just ending off with here. And the question is how could this work on L1? That's a very good question. We have a couple of ideas. Actually, block building on Ethereum is not very decentralized. It's actually three block builders that have like 90% of the block building. So I would say it's primarily a bid equation. Because if we convince these block builders that they can make more money by enforcing assertions then we have 90% of the blocks that are credible. And then as a dApp one dApp could say that actually I want to accept transactions only from blocks that are included in these block builders. But because we have 90% that's most of the blocks. So that's, for example, a very naive idea that we have right now of how this could work. The next question we have here is Can I just remove this? It's here. Doesn't this also make everything a tiny bit more easily censorable? Depending on how you would define easily. Because we're not adding any we're not adding any features that do not already exist. For example I can upgrade my smart contract tomorrow with my multisig and then stop anyone from interacting with it. Nothing stops me. What stops me is that I'll probably get sued and go to jail. I would say that we are not We are making it easier for dApps to make these unilateral decisions. But first you can do a couple of things like have time blocks for the assertion so that the community has time to react to them. But also I think the upside of what we're getting here is huge. Because right now we can enforce things that we couldn't enforce before. We can prevent flash loan attacks Oracle manipulation attacks. The Bybit hack, for example. Imagine if you could say that I don't want my safe to never be upgraded without my knowledge. So the Bybit attack wouldn't have happened. So I think the upside is considerable. And that's why we're seeing a lot of interest. We have another one here. A protocol's assertions could be broken without a transaction touching the contract. For example Uniswap X times Y equals K can be broken if USDC is hacked and balance is transferred. How do you handle this? Can you repeat the question? It's also here at the top. A protocol's assertion could be broken without a transaction touching the contract. For example Uniswap X times Y equals K can be broken if USDC is hacked and balance is transferred. How do you handle this? I read that question as what happens if the USDC Oracle Yeah, I guess for this particular use case I'll have to think about it. I'm not sure. We'll move to the next one here. Is it not feasible to simulate the undesirable state change or execute it in a TEE prior to inclusion and then just dropping the transaction from the mempool? Yeah, this is exactly what we're doing. Perfect. But we saw the TEE first. The TEE is an implementation detail. Got it. How do assertion writers verify that they should have the powers to censor transactions related to a given smart contract? That's probably the it's a very interesting question. It's both a philosophical question like who should be in charge to add an assertion. For example, for C-port it's a protocol with no owners or no admin functionality. So it's a philosophical question on which contract should be supported and who should be able to add assertions and how you do it. To which we have a few ideas. So we have started Yes, we are coming for others. We have started with the owner interface or basically supporting smart contracts that have clearly an admin functionality so their users have the expectation that there is some admin functionality. There is someone with the power to change things either to multisig or it's governance, for example, AVE. And we want to expand. Right now we don't, you know, if someone said should C-port should we support C-port or not? I don't have a good answer for that. It's something that we are thinking and evolving in collaboration with the networks we work with and the DAFs to identify first what are the user expectations and then the technical solution which is usually the simple thing. Thank you so much. That was the last question. Thank you very much for the talk. Thank you for the great answers to all the questions.
