# Security Council Report: Scroll Mainnet Emergency Upgrade on 2025-05-26

**URL:** <https://forum.scroll.io/t/security-council-report-scroll-mainnet-emergency-upgrade-on-2025-05-26/810>\
**Category:** General\
**Tags:** protocol, councils, technical, security-council\
**Created:** [June 3, 2025, 2:47am UTC](https://forum.scroll.io/t/security-council-report-scroll-mainnet-emergency-upgrade-on-2025-05-26/810 "2025-06-03T02:47:23Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![haichen](https://avatars.discourse-cdn.com/v4/letter/h/c5a1d2/32.png) [@haichen](https://forum.scroll.io/u/haichen)\
**Post date:** [June 3, 2025, 2:47am UTC](https://forum.scroll.io/t/security-council-report-scroll-mainnet-emergency-upgrade-on-2025-05-26/810/1 "2025-06-03T02:47:23Z")

</div>

Authors: The Scroll Security Council

## Overview

On May 26, the Scroll Security Council performed an emergency upgrade to the Scroll mainnet to address a bug discovered in one of the dependencies of the OpenVM prover.

Scroll worked with the Plonky3 and Axiom teams, as well as the Scroll Security Council, to promptly review and fix the bug, and deploy the patch in this emergency upgrade.

## Summary of the Vulnerability

The Plonky3 team found [two bugs](https://x.com/dlubarov/status/1929723510622244941) in the FRI verifier. Axiom reviewed the bug and found that the fix would result in the vkey change. That meant that the fix required upgrading the Scroll on-chain verifier contract.

Here is the overview of the missing randomness in mixed domain handling in FRI folding:

The folding needs to add `beta^2` (since `beta` is already used in the folding) to roll in new terms from reduced opening. So in function `verify_query`, the `betas_squared` of length `log_max_height` will be passed in and used for random linear combination.

Below are the native verifier changes and recursion verifier changes.

**Native verifier change (in Plonky3)**

```diff
  if let Some(v) = inputs_iter.next_if(|v| v.len() == folded.len()) {
- izip!(&mut folded, v).for_each(|(c, x)| *c += x);
+ // Each element of `inputs_iter` is a reduced opening polynomial, which is itself a
+ // random linear combination `f_{i, 0} + alpha f_{i, 1} + ...`, but when we add it
+ // to the current folded polynomial, we need to multiply by a new random factor since
+ // `f_{i, 0}` has no leading coefficient.
+ izip!(&mut folded, v).for_each(|(c, x)| *c += beta.square() * x);
  }

```

**Recursion verifier change (in OpenVM)**

```diff
      // Generate the beta squares
+ builder.iter_ptr_set(&betas_squared, beta_sq_ptr, sample * sample);
...
      // Later in `verify_query`, use the randomness to folding polys
+ builder.assign(&folded_eval, folded_eval + beta_sq * reduced_opening);

```

`num_queries` has also been updated accounting for poles. See the diff of `stark-backend` listed below.

**Release and code diffs:**

- `plonky3`: [Missing final polynomial degree check in FRI verifier · Advisory · Plonky3/Plonky3 · GitHub](https://github.com/Plonky3/Plonky3/security/advisories/GHSA-f69f-5fx9-w9r9) ([patch](https://github.com/Plonky3/Plonky3/commit/e784f44924e12a5a6799f3b03c18d1fa6b1a111e))
- `stark-backend`: [Release v1.1.0 · openvm-org/stark-backend · GitHub](https://github.com/openvm-org/stark-backend/releases/tag/v1.1.0) ([code diff](https://github.com/openvm-org/stark-backend/compare/v1.0.1...v1.1.0))
- `openvm`: [Release v1.2.0 · openvm-org/openvm · GitHub](https://github.com/openvm-org/openvm/releases/tag/v1.2.0) ([code diff](https://github.com/openvm-org/openvm/compare/v1.1.2...v1.2.0))

## Timeline

- 3 May: Received circuit vulnerability notice from the Plonky3 team.
- 3-20 May: Scroll dev team developed and tested the patched OpenVM circuits on a private shadowfork network.
- 23-24 May: The [Scroll Security Council](https://scroll.io/blog/introducing-scroll-security-council) verified the fix independently and signed the [emergency verifier update](https://etherscan.io/tx/0xf813ae648244dc212fa43bcf739f8ba8469d6ef8362f17c91967149ee2ed26af).
- 26 May: Scroll executed the on-chain verifier update in [this transaction](https://etherscan.io/tx/0xba98265b96c11b6b22d44f813082daf29a4dd0dd3dc40057ac4f9f6619362d0d). Pending blocks were re-proven and finalized shortly after this.

## Retrospective

This bug could not be meaningfully exploited on Scroll because the sequencer and provers are not permissionless. As we move toward decentralizing these components, we plan to implement additional safeguards, such as multi-proof system, to mitigate the risk of circuit and prover vulnerabilities.

## Acknowledgement

We thank the Plonky3 and Axiom teams for the finding and disclosure of the bug and their prompt fix.
