(Breaking) Circuits on Ethereum

What Are Circuit Breakers

If you’re reading this, you’re probably already familiar with DeFi. In that context, Circuit Breakers (CBs) are mechanisms integrated into DeFi protocols to temporarily halt or limit transactions, mainly token outflows, under certain conditions. These conditions are typically predefined and are triggered when unusual or suspicious activity is detected, such as an abnormally large withdrawal of funds in a short period. These circuit breakers aim to safeguard against potential security breaches or financial anomalies.

The leading advocates of circuit breakers in DeFi, as of late, argue for their implementation given the following nuances in crypto:

  • UX Challenges, Custody Responsibility & DYOR: The general population, accustomed to traditional banking systems, may not be fully prepared for the responsibility of self-custody of funds that DeFi entails. In addition, the ability to invest in various financial products with little knowledge of their inner workings or proper research (DYOR - Do Your Own Research, a well-known meme in the web3 world) also poses a problem for the end-user.

    Circuit breakers could act as a safety net, providing security and trust in these systems.

  • Preventing Composability Attacks: In the interconnected world of DeFi, where protocols often interact and rely on each other, circuit breakers can prevent composability attacks. These attacks occur when an entity exploits the outflows from one protocol to manipulate or attack another, potentially leading to cascading failures across the ecosystem.

I’m not a big proponent of circuit breakers, and I’m here to explain why these implementations warrant further contemplation. It is crucial to maintain a neutral tone when discussing security-improving standards for the ecosystem, and I’ll try to do so.

CBs are not a one-size-fits-all solution and come with challenges, such as potentially creating denial-of-service vulnerabilities. Let’s dig into it.

Looking Back

The concept of outflow limitations in banking has its roots in the early history of banking and financial regulation. These measures were typically introduced as a response to financial crises or situations where the banking system was at risk.

  1. Bank Runs and Early Regulation: The most common reason for introducing outflow limitations was to prevent or mitigate the effects of bank runs. A bank run occurs when many customers withdraw their deposits simultaneously, usually due to fears that the bank will become insolvent. This phenomenon was particularly prevalent during the early 20th century, including during the Great Depression.

  2. The Great Depression and Banking Reforms: The Great Depression in the 1930s led to significant banking reforms, particularly in the United States, with the introduction of the Banking Act of 1933 (also known as the Glass-Steagall Act). This act, among other things, aimed to restore public confidence in the banking system and included provisions for banking regulation that indirectly affected outflow capabilities.

  3. Modern Banking Regulations: In recent times, banking regulations have continued to evolve, particularly during financial crises like the 2008 global financial crisis. These regulations often include liquidity requirements and other measures that can act as de facto outflow limitations, ensuring that banks maintain a certain level of liquid assets to meet potential withdrawal demands.

  4. International Examples: Different countries have implemented outflow limitations in various forms, often in response to specific economic crises or challenges. For example, during the European debt crisis, certain banks in countries like Greece and Cyprus imposed withdrawal limits to maintain financial stability.

Wrapping up, it’s clear that outflow limits were mainly a response to bank runs. But in DeFi, things are different. Most DeFi platforms are made to have atomic settlements (i.e., settle in a single transaction). This setup naturally dodges the classic bank run issue.

These systems are made to run 24/7 settle without human interaction. So it is obvious to me that the reason “circuit breakers” were introduced in the past is not why we are touting them today.

Shut Up And Show Me The Code!

This entire piece started based on an intuition of mine that implementing circuit breakers in the systems we have designed would turn the whole crypto ecosystem into the same infrastructure banks had created.

After careful research, I changed my views on the subject. However, the two first points still stand very valid.

CBs increase the attack surface of a project, and as we saw with the Wise Lending attack recently (read the linked thread from Daniel for an excellent deep dive into it), adding code to make things safer might do the exact opposite:

In addition, and arguably more importantly, CBs are essentially a Denial-of-Service “feature.” Notice I am air-quoting feature because, after over seven years of reviewing the security of many of Ethereum’s significant protocols, my team and I have consistently flagged anything that could prevent the systems from executing continually as a vulnerability.

Taking a step back

Let us take a breather before I explore my potentially biased views about this solution and look at the current implementations (with none of them being live that I am aware of).

Here is the Ethereum Magicians post discussing the ERC for the Circuit Breaker standard: https://ethereum-magicians.org/t/eip-7265-circuit-breaker-standard/14909.

And the ERC itself: https://github.com/ethereum/EIPs/pull/7265/files#diff-ecfb870fcc81bdae3f4d19e1a26384c7038345396d61751b1c0bb9bd3637588a.

For some visual context, here is the message sent with the PR to the EIP repository on GitHub:

Implementation, which is extraordinarily similar in design to @Elliot0x:


Revisiting My Opinions

Granted, the canonical implementation is well-built and mitigates many of the issues I raised when I first started talking about CBs publicly. Mainly through the use of a buffer mechanism that accounts for inflows as well as outflows, as perfectly explained by @Philogy in the ERC docs:

Let’s go back to the list in the tweet I presented at the beginning of the article and analyze how my perception changed!

Human dispute processes. ✅

The CBs presented are completely automated, so they generally don’t suffer from this problem. There is a dilemma at play here, though, between delayed, third-party settlement and the prevention of griefing attacks.

As a consequence of the above, I wouldn’t qualify this as an issue anymore.

Increased attack surface ☑️

This is somewhat solved in the implementations I looked at.

I say “somewhat” because the modules to be added are meant to exist in isolation and not completely intertwined with the project’s code. This means your codebase can update storage counters and then read from them, but if there is a flaw in this code, the extent of the damage is that the circuit breaker doesn’t work anymore.

The flip side to this assumption is that if you poorly implement the invariant in your code on the outflow limits and give it some other access control to your system, that might create many problems. But then again, there are reference implementations in the repositories for you to analyze, hopefully mitigating this problem.

Getting the time window right (I have no idea how you’d do this!). ☑️

This is openly recognized by Philogy in the docs; however, I think the importance of how these choices might impact the operations of protocols is greatly understated. In his words:

Parameter Choice

Generally these are relative subjective reasons to assign these parameters, more research is required.

I agree, but I think that the project's needs mutate too often, and the lack of proper care will hinder the protocol badly. This raises yet another problem in this vertical.

Assuming that the limits should be time-variant (e.g., they should probably start small when the project launches and increase with maturity), the algorithm to change said parameters would be another scope creep or bad-opsec door open to attackers. Not the most worrying aspect but also not the least worrying one.

Griefing attacks. ❌

And we finally get to the elephant in the room. This is both recognized in the docs and a tweet by Philogy. A tweet that recognizes the dilemma I stated above and signals a preference for a human-bound settlement mechanism, which might reopen the first two problems I deemed as solved above.

Now, this is where our hopes and wishes start to differ wildly. 😂

I do not believe transitioning into a settlement layer of third parties is a good solution, and whether it is an improvement is very much up for debate.

Even in CBs’ current form, legitimate inflows are effectively not protected by the limiters (for a certain period), and, more worryingly, legitimate outflows can pause the entire system!

Taking aside the implementation is hijacking the Pause state from Open Zeppelin libraries, which might be used for something other than just transfers (easily solvable); the fact a single actor can utilize a feature to globally pause in and outflows gives me the chills. 😰


As Philogy recognizes and eloquently puts in the FAQ:

Elastic-to-Main buffer time frame ratio (Tl/Tm)

This is the biggest ??? at the moment. The lower the ratio the faster new deposits are protected but the easier the protocol is to DoS by just depositing, waiting for the elastic buffer to decay and withdraw.

They are alluding to how certain parameters affect the DoS-ability of the system.

Without getting into too much technical detail (please read the docs for that; they’re really well written), I am a big proponent of a huge Tl. However, that becomes impractical as it entirely defeats the CB’s purpose.

Last Considerations And Macro Suggestions

I don’t think Circuit Breakers are inherently bad; on the contrary, I think they’re a good development. We need to work way more on their shortcomings. WAGMI, I guess, CBs included.

Shut up about it and solve it

Well, I guess you must put your work where your mouth is.

Assuming that the biggest danger here is the legitimate inflows creating space for malicious attacks, the only idea I can come up with is to “limit” legitimate inflows at the front-end level. Making it difficult for your users to deposit money.

Don’t get me started on the commercial pains this brings. Your CMO will for sure cry. But it kinda works?

This will probably drive your users mad, but with good UX, it can be a good workaround. 🤷‍♂️

Financial considerations

Since this is a solution tailor-made for financial products being built on Ethereum, I’d argue that the imposition of a rate limiter on your product actually makes its token a derivative of its original function.

The rational markets will price in the fact that you cannot exit your positions immediately (i.e., settle atomically). This could even generate opportunities to tokenize this disparity, just like we saw with LSTs (h/t @bees_neeth).

It even prevents whales that look for liquid investments (significant upside of blockchain-related products, in my opinion) from participating entirely (e.g., a whale being unable to withdraw their money instantly and instead having to wait

Tmr<TotalValueInvested>\frac{T_m * r}{<Total Value Invested>}

seconds to take it all out.

All in all, CBs have an undesired side effect of creating a much more unstable asset than its non-CBed counterpart.

Alignment considerations

Reverting from the polarizing position I assumed on this tweet:

I do not think implementing CBs is turning protocols into the horrible mess of financial systems today. At the very least, Ethereum is a much more transparent substrate than the one banks have, and that alone is a million light-years ahead of any bank-related infrastructure.

However, the fact we are partially breaking atomic settlement is unavoidable. In the same way, CBs possibly prevent composability issues, a single CBed protocol in a chain of interactions breaks atomicity for the entire chain should the values be above what is deemed acceptable for the CBed protocol. I find this problematic because my idealized version of Ethereum and DeFi is permissionless, but we should still talk about it.

Two-pronged final boss

My final suggestion is still the same as the tweet above. Possibly a bit uninspired, but I gave it some thought.

Many of you will probably retort, saying that it’s even worse for a project to fractionalize reserves. In other words, if you deploy two versions of your protocol, you’d be tearing apart your TVL into two uncommunicative parts. This isn’t entirely true. We can reframe these assumptions.

If one of the parts has atomic settlement and the other doesn’t, the value fraction needn’t be absolute. The part with instant settlement can still provision the part that doesn’t; it's just that the reverse isn’t true. “Fractionalization,” in this case, is a directed edge.

You could build layers on top of both systems that take care of this bridging automatically or just let the markets do their thing and provision the CB-enabled systems with their non-CBed counterparts for a premium.

I'll try to explain it with an example.

Say you deploy a Uniswap v2 pool with a CB embedded, specifically a pool for the USDC-ETH pair. This pool might lack instant settlement for certain volume amounts, but the original pool for the pair doesn’t. So markets, doing what markets do, will arbitrage between these pools, bridging the liquidity from the non-CB pool to the CBed one, should the opportunity arise. The contrary might not be true, though, because of the limits.

In other words, what I’m saying is that the TVL for Uniswap v2 with Circuit Breakers is the sum of the reserves of all the pools with and without CBs, and the TVL for “normal” Uniswap v2 is the sum of the reserves of only the pools without CBs.

Let me draw it for y’all:

I know this has the added drawback of dispersing the team’s attention over multiple copies of the same system, but then again, if CBs are meant to be simple, this shouldn’t be too much of a hassle.


Sadly, I am not proposing a technical solution for the problem (in part because I don’t think it’s needed; markets will do their thing) but rather a reframing of the mindset of fractionalized value, and I hope it is enough to convince you, the developer of the Next Big DeFi Thing™, to at least consider giving optionality to your users and the ecosystem.

TL;DR

  • Circuit Breakers are a good step forward. But it feels like we haven’t tied our laces yet, so proceed cautiously.

  • The increased attack surface doesn’t seem extremely problematic with their canonical implementations.

  • They still present high denial-of-service risk for projects implementing them.

  • You should seriously consider deploying versions of your system with and without circuit breakers. Fractionalized reserves are not a real problem if you do.

All of this might boil down to core beliefs, and I have always been for optionality, freedom of choice, less human interaction, and less human dependence in our systems, so please think of me as you deploy your next circuit breaker. 🥹


If you liked what you read and it vibed with you, I have some good news, you can interact more with me in these two places:

Creed

Having previously co-founded (and still advising) the Consensys Diligence team, I saw a need for a more decentralized version of a security boutique to exist and decided to start a new endeavor called Creed.

If you need security or design help while building your systems, check out https://thecreed.xyz/ or email goncalo@thecreed.xyz.

Ethereal Ventures

If you’re a founder looking to fundraise, come talk to Ethereal Ventures, where I am a technical partner. EV takes a founder-first approach to all investments, and we are here to help you through technical and nontechnical challenges during your course.

Check us out at https://ethereal.xyz or email me at goncalo@ethereal.xyz.

Subscribe to Gonçalo
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.